开发者(KaiFaX)
面向开发者、程序员的专业平台!什么是垃圾GC(GarbageCollection)负责清理的垃圾是指:当变量被删除之后,该变量原来连接的容器zval还存在,导致现在又没有任何变量名指向该zval。此时该zval就是需要被回收的垃圾。
什么时候会造成这个情况,可以先了解PHP内存泄漏。
生成垃圾下面配合官方PHP垃圾回收中的配图进行说明。官方文档中的图可能不仔细分析会觉得很难懂,下面我配以一段代码进行说明
$a=one;
$b=array($a);
$b[]=$b;
xdebug_debug_zval(a);
xdebug_debug_zval(b);
打印的结果
a:(refcount=,is_ref=0)=one
b:(refcount=,is_ref=1)=array(
0=(refcount=,is_ref=0)=one,
1=(refcount=,is_ref=1)=...,
)
用图表示
这时候unset($b)就会出现如下情况
这时候原来$b指向的zval容器(假设命名为zval_b)的连接断开了,就导致了内存泄漏,而$a所指向的zval容器的连接还存在。zval_b也就是我们所说的垃圾。那么GC如何将其识别出来呢?
垃圾回收的实现1.上面的zval_b被视为可能的垃圾存放到根缓存区。
.算法会对每个节点(初始节点本身不做减1操作)所包含的zval进行refcount模拟减1操作,现在对zval_b这个容器里的所有节点进行操作,首先对[0]号元素的节点进行模拟减1操作,然后对[1]号元素的节点模拟进行减1操作。只是模拟并不是真正的减1。
3.算法会对每个节点(初始节点本身不做操作)所包含的refcount0的zval进行refcount加1操作,现在对zval_b这个容器进行操作,[0]号元素的refcount=0所以不予以处理,然后对[1]号元素的节点进行加1操作。如此,就确定了垃圾部分,将其标记,同时也对非垃圾进行了还原。
4.遍历zval_b节点,将上步中标记成垃圾的节点zval释放掉。
来源:Mengkangsland