#php7 ガベージ コレクション メカニズムの詳細な説明
著者は数日前にこのトピックに興味を持ったので、ネットで検索したところ、ほとんどがphp 5のガベージコレクション機構に関するものでした。php5からphp7へのGC部分の変更は比較的小さいですが、やはり別途ブログ投稿する必要があると思います。特に明記されていない限り、PHP のバージョンは 7.2 です。PHP の変数によって占有されているスペースを手動で再利用する必要はありません。カーネルがこの部分の作業を処理します。 C と比較すると、これにより操作が大幅に容易になります。 この記事では主に変数の GC メカニズムについて説明しますphp GC を理解する場合、php 変数の基礎となる実装を紹介する必要があると感じます。zvalの構造
// php 变量对于的c结构体 struct _zval_struct { zend_value value; union { …… } u1; union { …… } u2; };
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;
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;
変数の自動リサイクル
PHP では、配列型変数とオブジェクト型変数を除き、ほとんどの変数は自動的にリサイクルされます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 = [1]; $a[1] = &$a; unset($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<
循環参照によって引き起こされるメモリ リーク
これらのゴミをクリーンアップするために、2 つの基準が導入されます# 参照カウントが減少した場合ゼロ、コンテナが配置されている変数 コンテナはクリア (解放) され、ガベージではありません # zval の参照カウントが削減後も 0 より大きい場合、コンテナはガベージ サイクルに入ります。次に、ガベージ サイクル中に、参照カウントが 1 減らされているかどうかを確認し、どの変数コンテナの参照が 0 であるかを確認して、どの部分がガベージであるかを見つけます。 循環参照は基本的に配列とオブジェクトにのみ現れます。オブジェクトはそれ自体が参照であるためです。オブジェクトと配列のリサイクル プロセス
php7 のガベージ コレクションは 2 つの部分で構成されており、1 つはガベージ コレクターで、もう 1 つはガベージ コレクション アルゴリズムです。 ガベージ コレクターは、ゴミの可能性がある前述の要素をリサイクル プールに収集します。つまり、変数の zend_refcount 情報がリサイクル プールに配置されます。リサイクルプールの価値が一定量に達すると一律に処理されます。 処理プロセスは比較的単純です。 リサイクル プール内のすべての変数を走査し、各変数に基づいて各メンバーを走査します。メンバーがまだネストされている場合は、走査を続けます。次に、すべてのメンバーのシミュレートされた refcount を -1 に設定します。このとき外部変数の参照回数が0の場合。そうすれば、それは明らかにゴミとみなされます。 0 より大きい場合、参照の数は復元され、ガベージ コレクション プールから取り出されます。ガベージ コレクションの原理
変数がガベージではない場合、そのすべてのメンバー変数の参照が 1 つ減らされた後、合計変数の参照が減らされます。絶対に0にはなりません。例
言うのはかなり難しいので、例を挙げてみましょう。初めて sf.gg を閲覧したときに GC に関する質問を見つけたので、それに答えました。 GC ガベージ コレクションのメカニズムについてトピックは次のとおりです//我的回答 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のガベージコレクションの仕組みを詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。