(推奨チュートリアル: PHP ビデオ チュートリアル)
すべての php変数は、zval と呼ばれる変数コンテナーに保管されます。
zval 変数コンテナには、変数の型と値に加えて、2 バイトの追加情報も含まれています。
最初の変数は is_ref で、この変数が参照コレクションに属しているかどうかを識別するために使用されるブール値です。このバイトを通じて、PHP エンジンは通常の変数と参照変数を区別できます。PHP ではユーザーが & を使用してカスタム参照を使用できるため、zval 変数コンテナにはメモリ使用量を最適化するための内部参照カウント メカニズムもあります。
2 番目の追加バイトは refcount で、この zval 変数コンテナーを指す変数の数を示すために使用されます。
すべてのシンボルはシンボル テーブルに存在し、メイン スクリプト (例: ブラウザを通じて要求されたスクリプト) や各関数またはメソッドと同様に、各シンボルにスコープがあります。
変数に定数値が割り当てられると、zval 変数コンテナが生成されます
Xdebug がインストールされている場合は、xdebug_debug_zval() を使用できます。この 2 つを確認してください
<?php $a = "new string"; xdebug_debug_zval('a'); //结果 a: (refcount=1, is_ref=0)='new string'
ある変数を別の変数に代入すると参照数が増加します
<?php $a = "new string"; $b = $a; xdebug_debug_zval( 'a' ); //结果 a: (refcount=2, is_ref=0)='new string'
unset()を使用すると参照数を減らすことができます
型と値を含む変数コンテナはメモリから削除されます
<?php $a = "new string"; $c = $b = $a; xdebug_debug_zval( 'a' ); unset( $b, $c ); xdebug_debug_zval( 'a' ); //结果 a: (refcount=3, is_ref=0)='new string' a: (refcount=1, is_ref=0)='new string'
<?php $a = array( 'meaning' => 'life', 'number' => 42 ); xdebug_debug_zval( 'a' ); //结果 a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=1, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42 )
既存の要素を配列に追加します
<?php $a = array( 'meaning' => 'life', 'number' => 42 ); $a['life'] = $a['meaning']; xdebug_debug_zval( 'a' ); //结果 a: (refcount=1, is_ref=0)=array ( 'meaning' => (refcount=2, is_ref=0)='life', 'number' => (refcount=1, is_ref=0)=42, 'life' => (refcount=2, is_ref=0)='life' )
配列内の要素を削除します
は、スコープから変数を削除するのと似ています。
削除後、配列内の要素が配置されているコンテナーの「refcount」値は減少します
<?php $a = array( 'meaning' => 'life', 'number' => 42 ); $a['life'] = $a['meaning']; unset( $a['meaning'], $a['number'] ); xdebug_debug_zval( 'a' ); //结果 a: (refcount=1, is_ref=0)=array ( 'life' => (refcount=1, is_ref=0)='life' )
配列自体をこの配列の要素として追加すると、興味深いことが起こります。
上記と同じように、変数に対して unset を呼び出すと、シンボルが削除され、その数は変数コンテナが指す変数コンテナ内の参照も 1
<?php $a = array( 'one' ); $a[] = &$a; xdebug_debug_zval( 'a' ); //结果 a: (refcount=2, is_ref=1)=array ( 0 => (refcount=1, is_ref=0)='one', 1 => (refcount=2, is_ref=1)=... )
参照カウントが増加すると、それは引き続き使用され、もちろんガベージには入れられなくなります。 参照カウントがゼロに減少すると、変数コンテナはクリアされます (解放)つまり、ガベージ サイクルは、参照カウントがゼロに減少した場合にのみ発生します。 -zero value
ガベージ サイクルでは、参照カウントが 1 減っているかどうかを確認し、どの変数コンテナの参照がゼロであるかを確認することで、どの部分がガベージであるかを見つけます。
#ten 1. リサイクル アルゴリズムの分析
すべての参照カウントをチェックする必要を避けるために、ガベージ サイクルを減らすことができます
このアルゴリズムは、考えられるすべてのルート (考えられるルートは zval 変数コンテナー) をルート バッファー (紫色でマークされ、ガベージの疑いと呼ばれる) に配置するため、考えられるすべてのガベージを同時に確保できます。 ルート (ガベージ ルートの可能性がある)バッファ内に 1 回だけ表示されます。ガベージ コレクションは、ルート バッファーがいっぱいの場合にのみ、バッファー内のすべての異なる変数コンテナーに対して実行されます。上の画像のステップ A を見てください。
ステップ B では、紫色の各変数の削除をシミュレートします。削除をシミュレーションする際、紫色以外の通常変数の参照回数が「1」減る場合があり、通常変数の参照回数が0になった場合は、再度その通常変数の削除をシミュレーションしてください。各変数の削除をシミュレートできるのは 1 回だけであり、削除のシミュレート後は灰色でマークされます。
ステップ C では、シミュレーションによって紫色の各変数が復元されます。リカバリは条件付きであり、変数の参照カウントが 0 より大きい場合、シミュレートされたリカバリが実行されます。同様に、各変数は 1 回だけ復元できます。復元後は黒でマークされます。基本的にはステップ B の逆の操作です。このようにして、回復不能な青いノードの残りの山が削除されるべきです。ステップ D でそれらをトラバースし、実際に削除します。
主なものは 2 つあります。ドメインはパフォーマンスに影響を与えます
1 つはメモリ領域の節約です
もう 1 つは、ガベージ コレクション メカニズムがリークしたメモリを解放するのにかかる時間の増加です
PHP のガベージ コレクション メカニズムは、リサイクル アルゴリズムが実際に実行されているときに消費時間を増加させるだけです。ただし、通常の (小規模な) スクリプトでは、パフォーマンスへの影響はまったくありません。
ただし、リサイクル メカニズムが実行されている通常のスクリプトの場合、メモリの節約により、より多くのスクリプトをサーバー上で同時に実行できるようになります。使用メモリの合計が上限に達していないためです。
この利点は、長時間実行されるテスト スイートやデーモン スクリプトなど、長時間実行されるスクリプトで特に顕著です。
(推奨チュートリアル: PHP ビデオ チュートリアル)
以上がPHP のガベージ コレクション メカニズムについて詳しく学ぶの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。