時間が変化し、それに応じて用語が変更されます。今日、私たちはそれを「ゴミリサイクル」ではなく「PHPリソースリサイクル」と呼ぶかもしれません。これはより密接にその本質を反映しています。それは単に破棄するのではなく、もはや使用されていないリソースを再利用することです。ただし、「ゴミリサイクル」の歴史に従うことがより一般的です。
コアポイント:
プログラムが生成したごみプログラムは、リソース、時には小さなリソース、時には大きなリソースを使用します。たとえば、データフィールド。プログラムは、データフィールド(シリアル番号など)を定義し、プログラムで使用できます。定義されると、このデータフィールドはメモリスペースを占有します。おそらく数バイトしかありませんが、それでもスペースです。各マシンまたはプログラミング環境には利用可能なスペースが限られているため、残りのスペースはこのフィールドが占めるスペースの量を減らします。プログラムが終了すると、消費するプログラムと任意のスペースが消え、利用可能な総スペースが最大サイズに復元されます。しかし、プログラムが終わらない場合はどうなりますか?これらのプログラムのいくつかを以前に書きました。彼らは美しい傑作であり、ワークショップの他の人が私がそれを作成したことに気付いたときはいつでも私はいつも幸せです。大規模なIBMコンピューターを自分で下に置くことほどあなたの能力を示すものはありません。あなたから注意をそらしなさい。しかし、一部のプログラムは、デーモンやその他のプログラムなど、永遠に実行するように設計されています。彼らが走るにつれて、彼らが生成するゴミの量は成長し続けるかもしれません。ロックされたリソースが大きい場合、システムに大きなマイナスの影響があります。したがって、各言語には、孤児リソースをクリアし、他のユーザーが利用できるようにし、利用可能なシステムスペースの合計量が同じままであることを確認する方法が必要です。幸いなことに、PHPはごみ除去のために3層の方法を使用します。
最初のレイヤー - スコープまず、ほとんどの言語と同様に、スコープが終了するたびに、そのスコープ内のすべてが破壊され、割り当てられたリソースが解放されます。スコープは、機能、スクリプト、セッションなどをカバーできます。スコープが終了すると、保持するものはすべてそれで終わります。もちろん、unset()関数を使用していつでもリソースを解放できます。これは、機能と方法がスコープをセットアップし、特定のメモリ使用量がいつ始まり、終了するかを指定し、存在する時間を制限するため、非常に重要な理由の1つです。それらは、グローバルエンティティではなく、可能な限り使用する必要があります。
2番目のレイヤー - 引用カウント第二に、ほとんどのスクリプト言語と同様に、PHPは参照カウントと呼ばれる手法を使用して、特定の変数を使用しているエンティティの数を追跡します。 PHPスクリプトで変数を作成するとき、PHPは、変数に割り当てられた値と他の2つの情報(IS_REFとRefCount)に割り当てられた値で構成されるZVALという名前の小さな「コンテナ」を作成します。 Zvalコンテナはテーブルに保存され、各スコープ(スクリプト、関数、メソッドなど)にはテーブルがあります。 IS_REFは、変数が参照セットの一部であるかどうかを示す単純なTrue/False値であるため、PHPが単純な変数か基準かを決定するのに役立ちます。 RefCountは、この値を使用している異なる変数の数を示す数値を保持しているため、より興味深いものです。つまり、変数$ dave = 6を定義すると、refcountが1に設定されます。 $プログラマー= $ daveと言うと、refcountは2に増加します。 PHPは、値6の2番目のZVALを作成しないことを知っています。このRefCountは、プログラムが終了すると、関数の範囲を残したとき、またはunset()を使用するときに減少します。 RefCountがゼロに達すると、ZVALが破壊され、保持する記憶が解放されます。もちろん、これは単純な変数の単純な例です。アレイまたはオブジェクトについて話すと、アレイ内の複数の値の要素に対して複数のzrefが作成されるため、状況ははるかに複雑ですが、基本処理は同じです。ただし、より複雑なPHPスクリプトで頻繁に発生する別の配列で配列を使用すると、問題が発生します。この場合、元の配列値が設定されると、配列値のrefcountが1に設定され、アレイが別の配列に関連付けられている場合、refcountは2に増加します。 2番目の配列の使用範囲が終了する場合、RefCountは1によって減少します。私たちは現在、値自体がもはや何にも関連付けられていない状況にありますが、ゼロよりも大きいことを表すコンテナ(ZVAL)の参照があります。最終的な結果は、元の配列で表されるストレージが解放されず、その量のメモリが何に対しても利用できないことです。多くの場合、この失われたストレージは小さいと思いますが、通常はそうではありません。最近のアレイは非常に大きなものになる可能性があり、発生するスクリプトがデーモンまたはほぼ連続的に実行される他の関数である場合、特に問題があります。この場合、結果の「メモリリーク」は、パフォーマンスやサーバーの運用機能に壊滅的な結果をもたらす可能性があります。
3階 - フォーマルガベージリサイクル
明らかに、参照カウントに基づくクリアリングには制限がありますが、幸運なことに、PHP 5.3はこの状況を支援する別のオプションを提供します。ごみ収集サイクルを解決したい特定のケースは、ZVALが減少しているがゼロではない場合です。基本的に、どの値をさらに減少させることができるかを確認し、ゼロで値を解放するためのループ。実際に起こるのは、PHPがすべてのルートコンテナ(ZVAL)を追跡することです。これは、ガベージコレクションがオンかどうかに関係なく行われます(ガベージコレクションがオンかどうかなどを尋ねることなくこれを行う必要があるため)。このルートバッファーは、最大10,000個の根を保持できます(固定サイズですが、これは変更できます)。それがいっぱいになると、ガベージコレクションメカニズムが開始され、このバッファーの分析が開始されます。 GCルーチンが最初に行うことは、ルートバッファーを繰り返して、すべてのZVALカウントを1減らすことです。これを行うと、チェックマークのような小さなタグで各タグをマークして、ルートを1回だけ減少させるようにします。その後、繰り返し、マーク(今回は小さな波状の線を使用して)をマークします。ゼロ以外の値は増加し、元の値に戻ります。最後に、再びスクロールし、バッファからゼロ以外のzvalをクリアし、refcountゼロの値でストアを解放します。 Garbage Collectionは常にPHPで有効になりますが、PHP.iniファイルのディレクティブZend.Enable_GCを使用してオフにすることができます。または、GC_ENABLE()およびGC_DISABLE()関数を呼び出すことにより、スクリプトでこれを行うことができます。上記のように、Garbage Collectionが有効になっている場合、ルートがいっぱいになったときに実行されますが、この設定をオーバーライドして、FITが表示されるときにgc_collect_cycles()関数を使用してコレクションを実行できます。また、PHPソースコードのZend/Zend_GC.CのGC_ROOT_BUFFER_MAX_ENTRIES値を使用して、ルートバッファーのサイズを変更できます。全体として、これにより、GCが実行されるかどうか、いつどこで実行されるかを制御できます。これは、リソースが少し集中しているため、自由に実行するようなものではないため、良いことです。
いつ使用するのか
ガベージコレクションはパフォーマンスに影響を与える可能性があるため、いつ使用すべきかを判断するために時間をかける価値があります。まず、公開しない限り(GC_COLLECT_CYCLES()関数を使用して)、正式なゴミコレクションはルートテーブル(10,000エントリ)がいっぱいになる前には発生しません。 t関数で起こります。小さなスクリプトで使用する必要がありますか?それはあなた次第です。 Garbage Collectionのような操作を実行するのは悪いことだと言うのは難しいですが、始まり、終了して消えてしまう小さくて速いスクリプトがあれば、報酬はあまりないかもしれません。ただし、サーバーが永続的なままである多くの小さなスクリプトを実行している場合、努力する価値があるかもしれません。本当に知る唯一の方法は、アプリケーションのベンチマークを設定して表示することです。もちろん、長期にわたるスクリプト、特に終わらないスクリプトがある場合、上記で説明したメモリリークの種類を防ぎたい場合は、ガベージコレクションが重要です。おそらく最も重要なことは、グローバル変数を最小化または排除し、変数をスコープに結合するように、常に優れたプログラミングガイドに従うことを試みる必要があります。スクリプトの最後ではありません。また、この状況はメモリリークにつながる可能性があり、正式なガベージコレクションプロセスの本当の目標であるため、配列またはオブジェクト参照オブジェクトが配列で使用される時期にも注意してください。
Fotoliaの写真PHPガベージリサイクルFAQ(FAQ)(記事が長すぎて擬似オリジナルの目標と一致しないため、FAQパーツはここで省略されています。FAQパーツの内容は元のテキストと非常に一致しています。変更後に変更される場合があります。)
以上がPHPマスター| PHPのゴミコレクションをよりよく理解しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。