ホームページ  >  記事  >  バックエンド開発  >  PHP のガベージ コレクションのメカニズムを例を使って詳しく説明します

PHP のガベージ コレクションのメカニズムを例を使って詳しく説明します

王林
王林転載
2019-08-29 13:55:312908ブラウズ

PHP ガベージ コレクション メカニズム:

1. PHP は、主に参照カウントを使用してメモリを自動的に管理し、不要なオブジェクトを消去できます

2 . Ref_count と is_ref ref_count は、この zval が参照される変数の数を識別する参照カウントで、0 の場合は破棄されます。 is_ref は、参照を強制するために & アドレス文字が使用されるかどうかを識別します

3. 循環参照メモリ リークの問題を解決するために、同期サイクル リサイクル アルゴリズムが使用されます。

たとえば、配列またはオブジェクトがそれ自体を周期的に参照して配列を設定解除する場合、refcount-1 がまだ 0 より大きい場合、それはガベージの疑いがあるとみなされ、走査され、refcount-1 の削除がシミュレートされます。 0の場合は削除、0でない場合は頑固なガベージ生成プロセスを元に戻す:

<?php
    $a = "new string";
?>
a: (refcount_gc=1, is_ref_gc=0)=&#39;new string&#39;

$aが別の変数に代入されると、$aに対応するzvalのrefcount_gcが増加します1

<?php
    $a = "new string";
    $b = $a;
?>

このとき、$a 変数と $b 変数に対応する内部ストレージ情報は、$a と $b が同時に文字列 "new string" を指しており、その refcount は 2a になります。 ,b: (refcount_gc=2,is_ref= 0)='新しい文字列'

unsetを使用して$b変数を削除すると、「新しい文字列」のrefcount_gcは1減って1になります

通常の変数の場合、これはすべて正常ですが、複合型変数 (配列とオブジェクト) では、さらに興味深いことが起こります:

<?php
    $a = array(&#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42);
?>

$a内部ストレージ情報は次のとおりです:

a: (refcount=1, is_ref=0)=array (
&#39;meaning&#39; => (refcount=1, is_ref=0)=&#39;life&#39;,
&#39;number&#39; => (refcount=1, is_ref=0)=42
)

配列変数自体 ($a) エンジンの内部には実際にはハッシュ テーブルがあり、このテーブルには 2 つの zval 項目の意味と番号があるため、実際にはそのコード行で合計 3 つの zval が生成されます。 zvals はすべて、変数の参照とカウントの原則に従います。図は次のとおりです:

PHP のガベージ コレクションのメカニズムを例を使って詳しく説明します

# 次に、要素を $a に追加し、既存の要素の値を $a に割り当てます。新しい要素:

<?php
    $a = array(&#39;meaning&#39; => &#39;life&#39;, &#39;number&#39; => 42);
    $a[&#39;name&#39;] = $a[&#39;meaning&#39;];
 ?>

$a の内部ストレージは、「life」の ref_count が 2 になり、42 の ref_count が 1:

a: (refcount=1, is_ref=0)=array (
&#39;meaning&#39; => (refcount=2, is_ref=0)=&#39;life&#39;,
&#39;number&#39; => (refcount=1, is_ref=0)=42,
&#39;name&#39; => (refcount=2, is_ref=0)=&#39;life&#39;
)

の参照を代入すると、配列を配列内の要素に変換すると、興味深いことが起こります:

<?php
    $a = array(&#39;one&#39;);
    $a[] = &$a;
?>

このように、$a 配列には 2 つの要素があり、1 つはインデックス 0 と文字 1 の値を持ち、もう 1 つはインデックス 0 と文字 1 の値を持ちます。インデックス 1, これは $a 自体への参照です 内部ストレージは次のとおりです:

PHP のガベージ コレクションのメカニズムを例を使って詳しく説明します

a: (refcount=2, is_ref=1)=array (
0 => (refcount=1, is_ref=0)=&#39;one&#39;,
1 => (refcount=2, is_ref=1)=…
)

array この zval の ref_count は 2 で、これは循環です参照。このとき、$a が設定されていないため、$a はシンボル テーブルから削除され、$a が指す zval の refcount_gc が 1 減ります。

そこで問題が発生します。シンボル テーブルに存在しなくなると、ユーザーはこの変数にアクセスできなくなりますが、$a が指す zval の refcount_gc が 0 ではなく 1 になるため、リサイクルできず、メモリ リークが発生します。新しい GC は、そのようなゴミをクリーンアップすることです。

循環参照メモリ リークの問題を解決するために、同期サイクル リサイクル アルゴリズムが使用されており、ref_count が 1 減っても 0 より大きい場合は、ガベージの疑いがあるとみなされます。

たとえば、配列またはオブジェクトがそれ自体を周期的に参照して配列の設定を解除する場合、refcount-1 がまだ 0 より大きい場合は、refcount-1 を一度削除するために走査およびシミュレートされます。と削除されますので、0でない場合は元に戻してください。

関連コンテンツをさらに知りたい場合は、PHP 中国語 Web サイトにアクセスしてください: PHP ビデオ チュートリアル

以上がPHP のガベージ コレクションのメカニズムを例を使って詳しく説明しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。