筆者は数日前にこの話題に興味を持ち、ネットで調べてみたところ、ほとんどがphp 5のガベージコレクション機構であることが分かりました。php5からphp7ではGC部分に変更が加えられていますが、比較的小さいものですが、まだいくつかあると思います。別のブログ投稿を作成する必要があります。 特に指定しない場合、PHP のバージョンは 7.2です。
PHP の変数によって占められている領域を手動で再利用する必要はありません。カーネルがこの部分の作業を処理します。 C と比較すると、これにより操作が大幅に容易になります。
この記事では主に変数の GC の仕組みについて説明します
記事ディレクトリ
推奨 (無料): PHP7 php GC を理解する際には、php 変数が実装されているということを紹介する必要があると感じます。フードの下。
zvalの構造
// php 变量对于的c结构体 struct _zval_struct { zend_value value; union { …… } u1; union { …… } u2; };主にガベージコレクションの話なので、u1 u2 Unionの機能を簡単に紹介します
u1 構造は比較的複雑です。主に変数の型を識別するために使用されると思います
u2 ほとんどは補助フィールド、変数の内部関数の実装、キャッシュの利便性の向上などです。 .
次は私たちです 主人公です
zend_value 構造体に埋め込まれた共用体でもあります
typedef union _zend_value { zend_long lval;//整形 double dval;//浮点型 zend_refcounted *counted;//获取不同类型的gc头部 zend_string *str;//string字符串 zend_array *arr;//数组 zend_object *obj;//对象 zend_resource *res;//资源 zend_reference *ref;//是否是引用类型 // 忽略下面的结构,与我们讨论无关 zend_ast_ref *ast; zval *zv; void *ptr; zend_class_entry *ce; zend_function *func; struct { ZEND_ENDIAN_LOHI( uint32_t w1, uint32_t w2) } ww; } zend_value;参照カウントは
の値に記録されますzvalzend_refcounted *counted
このタイプ、ガベージ コレクション メカニズムもこれに基づいています。
typedef struct _zend_refcounted_h { uint32_t refcount; /* reference counter 32-bit */ union { struct { ZEND_ENDIAN_LOHI_3( zend_uchar type, zend_uchar flags, /* used for strings & objects */ uint16_t gc_info) /* keeps GC root number (or 0) and color */ } v; uint32_t type_info; } u; } zend_refcounted_h;すべての複合型の定義は、
zend_refcounted_h 構造体で始まります。参照カウントに加えて、この構造体には GC 関連の構造体もあります。したがって、GC リサイクルを行う場合、GC は行われません特定の型を気にする必要はありませんが、すべて
zend_refcounted* 構造体として処理できます。
#変数の自動リサイクル
array を除きます
object 型変数、残りのほとんどは自動的にリサイクルされます。
PHP 通常の変数のリサイクルは、変数への参照の数に関係します。
$a = 1; $b = $a; xdebug_debug_zval('a'); $a =10; xdebug_debug_zval('a'); unset($a); xdebug_debug_zval('a');結果
a: (refcount=2, is_ref=0),int 1 a: (refcount=1, is_ref=0),int 10 a: no such symbol
$a =10の場合、PHPのCOW(コピーオンライト)メカニズムが関与していることがわかります。 , $b は元の $a をコピーして両者の参照関係を解除しますので、a の参照数(refcount)は 1 になります。
$a = [1]; $a[1] = &$a; unset($a);unset($a) 前の $a の型は参照型です
a: (refcount=2, is_ref=1), array (size=2) 0 => (refcount=1, is_ref=0),int 1 1 => (refcount=2, is_ref=1), &array<p><img src="https://img.php.cn/upload/article/000/000/052/b5a6578d3bb66f0539d3f3981d5b0923-0.jpg" alt=""></p>unset($ a) その後、次のようになります。<p></p><p><img src="https://img.php.cn/upload/article/000/000/052/8e8e7fe4611fd81045139c68c9a2afe3-1.jpg" alt=""></p>このとき、<p>unset<code> を実行すると、refcount が 2 から 1 に変わります。 $a を指す内部参照なので、外部で占有しているスペースは破壊されません。 </code></p>その後、外部参照が壊れていて使用できません。 C言語でワイルドポインタと呼ばれる「オーファン」となります。 phpでは循環参照といいます。メモリーリーク。変数を破棄したい場合は、php スクリプトが終了するまで待つだけです。 <p></p><p>循環参照によるメモリ リーク<strong></strong></p>このガベージをクリーンアップするために、2 つの基準が導入されます<p></p>
php7 のガベージ コレクションは 2 つの部分で構成されます。1 つはガベージ コレクターで、もう 1 つはガベージ コレクション アルゴリズムです。
ガベージ コレクターは、ガベージである可能性がある前述の要素をリサイクル プールに収集します。つまり、変数
zend_refcount>0 がリサイクル プールに配置されます。リサイクル プールの値が一定の量に達すると、均一に走査されます。模擬削除を実行します。zend_refcount=0
の場合、ゴミとみなされ、直接削除されます。 リサイクル プール内のすべての変数を走査し、各変数に基づいて各メンバーを走査します。メンバーがまだネストされている場合は、走査を続けます。次に、すべてのメンバーのシミュレートされた refcount を -1 に設定します。このとき外部変数の参照回数が0の場合。そうすれば、それは明らかにゴミとみなされます。 0 より大きい場合、参照の数は復元され、ガベージ コレクション プールから取り出されます。
変数がガベージではない場合、そのすべてのメンバー変数の参照が 1 つ減らされた後、合計変数の参照が減らされます。絶対に0にはなりません。 #########例######
说的比较死,不如举个例子。刚刷 sf.gg 的时候看到一道关于 GC 的题,我回答了一波。关于GC垃圾回收机制
PHP7 はガベージ コレクションのメカニズムを説明します如下
//我的回答 1、只要zval.value的refcount减一,然后缺其refcount的值不为0那么它就可能是垃圾,进入垃圾周期。 2、进入垃圾池遍历所有成员,包括其嵌套的成员,都对其做 refcount-1的操作,看外部的引用是否为0。 那么对于 题主的问题来说, 首先,你要想$a为垃圾,一定要先对 unset($a)操作,那么此时 $a的 refcount = 2 对于$a[0] refcount-1 不影响外部的$a, $a[1] refcount-1 ,此时 $a的 refount=1 $a[2] refcount-1 ,此时 $a 的 refount=0 模拟减结束,那么此变量被当成垃圾回收。
更多免费学习推荐:PHP7教程
以上がPHP7 はガベージ コレクションのメカニズムを説明しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。