2012-02-25 74 views
2

私はいくつかのPHPメモリベンチマークを行っていますが、ガーベッジコレクタを最適化してメモリ消費を減らす方法があるかどうかは疑問です(JAVAなどの他の言語でも可能です)。PHPのガベージコレクションとメモリの最適化

私は、php.iniのGCに関連するカスタマイズ可能なパラメータは、session.gc_probability,session.gc_divisorsession.gc_maxlifetimeという3つしか見つかりませんでした。これはセッションのみであり、私はそれをベンチマーキングしていません。

可能な最適化循環参照を避けたり、gc_collect_cycles()(この記事のおかげでhttp://www.alexatnet.com/comment/86)を呼び出すことによってガーベジコレクションサイクルを強制するなど、これまでのコード関連がわかっています。

誰かが、PHPのメモリ管理に関する設定の秘訣や良い方法を知っていますか?

+0

コンフィギュレーションディレクティブでは何もできません。メモリ使用量を減らすような方法でコードを書いてください。それ自体が大部分の「プログラマ」のミステリーです。 –

+0

実際にヒットしない限りメモリ消費量やGCの問題によるパフォーマンス上の問題がありますが、ほとんどの場合、それは心配しません。[タグ:マイクロ最適化] – GordonM

答えて

4

私が知る限り、時刻tでのメモリ使用量を最小限に抑えるのに、gc_collect_cycles()のコレクションを強制することが最も近い方法です。

GCは当然のことながら時間制約付きの操作であり、アプリケーションは決して非常にメモリに拘束されることはめったにありません。プログラムの実行中にGCランを不必要にトリガするオプションを提供することは実際には意味がありません。これに沿ってPHP で、サイクルコレクタをオンデマンドでオン/オフする機能(gc_enable()gc_disable())を提供していますので、時間をかけてコードを最適化することができます(もちろん、GCのオーバーヘッドを避けることができます)これがどのように役立つのかを見るのは簡単です。

一般的に、PHPは哲学によってメモリ管理やGCなどのトピックを避けており、実際の見通しのためにベンチマークはおそらくそれを考慮する必要があります。

これが役に立ちます。

+0

実際、私はこれらの種類のgc micro-最適化。しかし、obvioulsy PHPのガベージコレクタは調整できません。私は確信したかった。ありがとう。 –

0

私は変数が不要になったときにunset()メソッドを使って変数をクリアします。

0

一般PHPSのメモリ管理で(また、マイクロ最適化を理由@ GordonMさんのコメント。にうなずき)は、すべてあなたが宣言した変数との使用のために箱から出して動作します。 concept refcountingを使用すると、PHPは変数がもう使用されていないかどうかを確認し、自動的にクリーンアップします。

ガベージコレクタは、オブジェクトが循環参照を持つ場合にのみ重要です.AはBを指し、BはAを指します。この場合、refcountingは機能しません。

PHPメモリには、潜在的にそれ以上使用されない可能性があるオブジェクトが正確に10.000ある場合、PHPガベージコレクタは、有効になっているとトリガします。デフォルトで有効になっています。実行時にgc_enable()gc_disable()で無効または有効にすることができます。

gc_collect_cycles()に電話して、これらのオブジェクトを手動でクリーンアップすることもできます。

しかし、必要に応じてこのプロセスを最適化するにはどうすればよいですか?サイクルコレクタを実行することは、10.000個の潜在的なオブジェクトから効率的または有用である必要はなく、それらの多くはまだ使用中であり、クリーンアップすることはできません。この場合、すべてのオブジェクトをチェックし、それらをクリーンアップしないことを決定するCPUサイクルを無駄にしています。これを行うとメモリー削減はありません。

通常、GCは長時間実行されるスクリプトでのみトリガされ、あまりにも多くのオブジェクトを作成すると短時間のWebリクエストでトリガされることがあります。一般的には、これをあまりにも多く考える必要はありません。デフォルトがユースケースの99%で動作するからです。

"garbage_stats" PHP拡張機能を使用すると、GCがどれぐらい効率的かつ高速に実行され、どのくらいのメモリが削減されたかに関するメトリックと統計情報にアクセスできます。 (フックはそれ以来のみ利用可能ですので)それは7+ PHP上で動作します:https://github.com/tideways/php_garbage_stats拡張子をインストールしている場合は、あなたがそれらを呼び出すことにより、CLIスクリプトのガベージコレクションの統計を見ることができます

:から

$ php -dgc_stats.enable=1 -dgc_stats.show_report=1 test.php 

Found 7 garbage collection runs in current script. 

Collected | Efficency% | Duration | Memory Before | Memory After | Reduction% | Function 
----------|------------|----------|---------------|--------------|------------|--------- 
     0 |  0.00 % | 0.01 ms |  365824 |  366320 | -0.14 % | gc_collect_cycles 
    10000 | 100.00 % | 2.75 ms |  4651320 |  491816 | 89.43 % | foo 
    10000 | 100.00 % | 3.54 ms |  4652784 |  493280 | 89.40 % | foo 
    10000 | 100.00 % | 2.11 ms |  4654248 |  494744 | 89.37 % | foo 
    10000 | 100.00 % | 3.26 ms |  4656168 |  496664 | 89.33 % | Test::foo 
    9000 | 90.00 % | 1.51 ms |  4694680 |  951176 | 79.74 % | Test::foo 
    10000 | 100.00 % | 3.11 ms |  5112272 |  952768 | 81.36 % | Test::foo 

をWeb(ApacheやFPMなど)のリクエストでは、この情報にアクセスしてログファイルに書き込むには、関数$runs = gc_stats();を使用できます。

この情報に基づいて、最適化を行うことができる唯一の判断を下すことができます。スクリプトの効率性に応じてスクリプト内のGCを有効または無効にする。