企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
### php5.3之前版本的垃圾回收机制 1. 当变量被引用时,refcount计数器+1 2. 当unset($a)或出现写时复制操作后,refcount计数器-1 3. php会根据refcount的值来判断是不是垃圾,如果refcount值减为0,php会将该zval容器当做垃圾释放掉。但是循环应用的变量无法回收(一般循环引用的变量出现在数组或者对象上) ### php5.3之后版本的垃圾回收机制 1. 如果refcount减少后大于0,会把这个变量放入缓冲buffer中,等缓冲buffer满了之后,在统一进行处理。 2. 一个变量只能加入buffer一次,为了防止重复加入,变量在加入后会把zend_refcound_h.gc_info设置为紫色,下次refcount减少时如果发现已经加入过了则不再重复插入。 3. buffer缓冲区是一个双向链表,等到缓冲区满了以后则启动垃圾检查过程。 4. 垃圾检查过程: (1). 遍历缓冲区,再对当前变量的所有成员进行遍历, (2). 把当前变量的所有成员的refcount减1. (3). 最后检查当前变量的应用,如果减为0,则为垃圾。 **注:算法思路,垃圾时由于变量中的成员引用自身导致的,那么就对变量所有成员减1,结果发现变量本身refcount变为0则就表明其引用全部来自自生成员。** 5. 垃圾检查具体实现: (1). 遍历buffer缓冲,将当前value标为灰色,然后对当前value的成员进行深度遍历,把成员value的refcount减1,并且也标为灰色。 (2). 再重复遍历buffer缓冲,检查当前value的refcount是否为0.如果为0表示确实时垃圾,则标为白色。如果不为0则排除了引用全部来自自身的可能,表示还有外部的引用,并不是垃圾。这时将不为0的成员refcount+1,并标为黑色。 (3). 再次遍历buffer缓冲,将非白色的变量删除,最终buffer缓冲中剩下的全部为真正的垃圾,并清除这些垃圾。