上QQ阅读APP看书,第一时间看更新
3.3 垃圾回收机制
要想了解PHP的垃圾回收机制,首先要弄明白以下问题:
● 什么样的变量会被回收?
● 什么时机进行回收操作?
● 回收步骤是什么?
● 垃圾回收机制解决什么问题?
1.回收规则
首先我们讲一下回收的基本规则,这解释了什么样的变量会被回收。
● 变量引用计数增加(被使用或被引用),就不会被回收。
● 引用计数减少到零,所在变量容器将被清除(free),直接清理不用进入回收机制。
● 仅仅在引用计数减少到非零值时,才会产生垃圾周期(garbage cycle),可能会被回收。
2.回收时机
当引用计数减少到非零值时,才会产生垃圾周期。举例(1)说明如下:
unset($a)之后,是否触发了垃圾回收机制?
答:否!
这里有一个易混淆的地方:当一个变量的引用计数变为0时,PHP将在内存中销毁这个变量,只是这里的垃圾并不能称之为垃圾。
这里的变量free后,所占有的空间进入内存池,并不需要触发垃圾回收机制。
而下面的例子(2)则会触发。
unset后,a的refcount由2变为1,是符合触发条件的。
3.回收步骤
(1)模拟删除。根缓冲区(root buffer)里的每个变量zval的refcount减1。
(2)模拟恢复。如果refcount不为0,则refcount加1;如果为0,则不加1。
(3)真的删除。删除所有refcount为0的zval。
4.机制特性
垃圾回收机制首先是可解决内存泄漏和循环引用问题的(如回收时机的例子2)。注意,并不是每次refcount减少时都进入回收周期,只有根缓冲区满额后在开始垃圾回收。这是性能与功能的tradeoff。其次是将内存泄漏控制在一个阈值以下。