Heim > Artikel > Backend-Entwicklung > Chat über den PHP7-Garbage-Collection-Mechanismus
PHP7Die Kolumne stellt den Garbage-Collection-Mechanismus vor
Empfohlen (kostenlos): PHP7
Artikel. Verzeichnis
Um unseren PHP-GC zu verstehen, halte ich es für notwendig, die zugrunde liegende Implementierung unserer PHP-Variablen vorzustellen.
zval-Struktur
// php 变量对于的c结构体 struct _zval_struct { zend_value value; union { …… } u1; union { …… } u2; };
Da es hauptsächlich um die Speicherbereinigung geht, hier eine kurze Einführung in die Funktion von u1 u2 Unionu1
Die Struktur ist meiner Meinung nach relativ komplex um Variablentypen zu identifizieren 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;
在 zval
的 value中就记录了引用计数zend_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*
结构来处理.
#变量的自动回收
在php中 除了 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(copy-on-write)机制,$b 会复制一份原先的 $a ,解除了他们之间的引用关系,所以a的引用次数(refcount)减少为1。
然后我们uset($a)之后 a的引用次数变为0。这就会被认为是垃圾变量,释放空间。
在举一个例子
$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/163e22c0271ab639b6a5080b1ccd0d58-0.jpg" alt=""></p><p>unset($a) 之后,就变成这样</p><p><img src="https://img.php.cn/upload/article/000/000/052/163e22c0271ab639b6a5080b1ccd0d58-1.jpg" alt=""></p><p>这时候,我们<code>unset</code>操作时refcount 由2变为1,因为有内部引用指向 $a,所以在外部 其所占用的空间并不会被销毁。</p><p>然后我们的外部引用已经被中断了,我们也不能使用它。它就成了一个“孤儿”,在c语言中叫做野指针。在php中叫做循环引用。内存泄漏。想要销毁变量的话,只能等 php脚本结束。</p><p><strong>循环引用造成的内存泄漏</strong></p><p>为了清理这些垃圾,引入了两个准则</p>
循环引用基本上只会出现在 数组和对象中,对象是因为它的本身就是引用
object和array的回收过程
php7的垃圾回收包含两个部分,一个是垃圾收集器,一个是垃圾回收算法。
垃圾收集器,把刚刚提到的,可能是垃圾的元素收集到回收池中 也就是把变量的 zend_refcount>0
的变量 放在回收池中。 当回收池的值达到一定额度了,会进行统一遍历处理。进行模拟删除,如果zend_refcount=0
u2
Die meisten davon sind Hilfsfelder, Implementierung interner Funktionen von Variablen, Verbesserung der Cache-Freundlichkeit usw.
zend_value
Es ist auch eine Struktur. Eine in
//我的回答 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 模拟减结束,那么此变量被当成垃圾回收。eingebettete Union zeichnet den Typ des Referenzzählers
zend_refcounted *counted
im Wert von zval
auf. Auch unser Garbage-Collection-Mechanismus basiert darauf. rrreeeAlle komplexen Typdefinitionen beginnen mit der Struktur zend_refcounted_h
. Zusätzlich zur Referenzzählung verfügt diese Struktur auch über GC-bezogene Strukturen. Daher muss sich der GC nicht darum kümmern über den spezifischen Typ, die alle als zend_refcounted*
-Struktur verarbeitet werden können.#Automatisches Recycling von Variablen
In PHP, außer array
und Die meisten der Variablen vom Typ object
werden automatisch recycelt. PHP Das Recycling gewöhnlicher Variablen hängt von der Anzahl der Verweise auf die Variable ab. Offizielles Beispiel
Ergebnis
rrreeeSie können sehen, dass $b das Original von $a kopiert, wenn $a =10
den COW-Mechanismus (Copy-on-Write) von PHP verwendet , wird die Referenzbeziehung zwischen ihnen freigegeben, sodass die Anzahl der Referenzen (Refcount) von a auf 1 reduziert wird.
Nachdem wir t($a) verwendet haben, wird die Anzahl der Verweise auf a zu 0. Dies wird als Müllvariable betrachtet und gibt Speicherplatz frei.
%E6%9B%B4%E5%A4%9A%E7%BC%96%E7%A8%8B%E7%9B%B8%E5%85%B3%E7%9F%A5%E8%AF%86%EF%BC%8C%E8%AF%B7%E8%AE%BF%E9%97%AE%EF%BC%9A编程教学!! Das obige ist der detaillierte Inhalt vonChat über den PHP7-Garbage-Collection-Mechanismus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!