パフォーマンス-スクリプト実行中のphpガベージコレクション
cronで実行されるPHPスクリプトがあり、実行に最大15分かかる場合があります。定期的にmemory_get_usage()を吐き出しているので、何が起こっているのかを確認できます。初めてそれが私の使用法を教えてくれたとき、私は10メガです。スクリプトが終了すると、114メガバイトになります!
PHPは、スクリプトの実行中にガベージコレクションを実行しますか?または、そのすべての記憶に何が起こっているのでしょうか?ガベージコレクションを強制するためにできることはありますか。私のスクリプトが実行しているタスクは、Drupalに数千のノードを毎晩インポートすることです。ですから、同じことを何度も行っています。
何か提案はありますか?
答え :
解決策:
重要なのは、グローバル変数が不要になったらすぐに
ローカル変数とオブジェクトプロパティは、関数がスコープ外になるかオブジェクトが破棄されると破棄されるため、明示的にunsetを呼び出す必要はありません。
PHPは、すべての変数の参照カウントを保持し、この参照カウントがゼロになるとすぐに(ほとんどの条件で)それらを破棄します。オブジェクトには1つの内部参照カウントがあり、変数自体(オブジェクト参照)にはそれぞれ1つの参照カウントがあります。参照coutnsが0に達したためにすべてのオブジェクト参照が破棄されると、オブジェクト自体が破棄されます。例:
$a = new stdclass; //$a zval refcount 1, object refcount 1
$b = $a; //$a/$b zval refcount 2, object refcount 1
//this forces the zval separation because $b isn't part of the reference set:
$c = &$a; //$a/$c zval refcount 2 (isref), $b 1, object refcount 2
unset($c); //$a zval refcount 1, $b 1, object refcount 2
unset($a); //$b refcount 1, object refcount 1
unset($b); //everything is destroyed
ただし、次のシナリオを検討してください。
class A {
public $b;
}
class B {
public $a;
}
$a = new A;
$b = new B;
$a->b = $b;
$b->a = $a;
unset($a); //cannot destroy object $a because $b still references it
unset($b); //cannot destroy object $b because $a still references it
これらの循環参照は、PHP5.3のガベージコレクターが機能する場所です。{を使用してガベージコレクターを明示的に呼び出すことができます。 -code-3}
。
参照カウントの基本およびマニュアルのサイクルの収集。
答え :
解決策:
PHP unset()を使用して、使用しなくなった変数を解放します。変数を単純に上書きする場合(たとえば、nullで)、これにより、GCはその変数に必要なスペースの量までしか削減できませんが、実際に参照値の破棄を許可する未設定ほどではありません。
使用するリソースなども適切に解放する必要があります。 空いているCPUサイクルがあるときや、メモリが不足し始めたときなど、GCは独自の裁量で自由に解放できるため、実行時にメモリが増加します。
答え :
解決策:
unset() を可能な限り使用し、使用済みメモリをより頻繁にチェックします。はい、phpはいくつかの条件で実行時にガベージコレクションを行います。
これは、php.netで役立つ
答え :
解決策:
メモリがそれほど増えている場合は、おそらくそれを解放していません。メモリリークが発生しました。変数の設定を解除したり、オブジェクトを破棄したり、スコープから外れたりしない限り、ガベージコレクションは役に立ちません。
ロードしたノードの設定を解除していませんか?私は何時間も実行され、何百万ものデータベースレコードを処理するPHPスクリプトを作成しました。問題はなく、メモリ使用量は非常に許容範囲内で上下します。
同様の質問
私たちのウェブサイトで同様の質問で答えを見つけてください。