PHP面试一战到底
上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。其次是将内存泄漏控制在一个阈值以下。