PHP垃圾回收机制
php中什么是垃圾?
垃圾主要是针对内存的, 如果一个对象, 并没有任何变量引用它,那这个对象就是垃圾.
为什么要清理垃圾?
如果php开启了很多内存空间,但是却没有销毁它.内存会一点点的被吃掉,最终导致内存溢出!
有人说php线程结束的时候会销毁所有的变量,关闭所有打开的句柄资源,不都是自动的吗?为什么我们还需要清理?
如果你写的php代码是个需要长时间执行的呢,例如弄成守护进程?
垃圾回收的机制
PHP如何找到垃圾
第一步, 从所有变量中找到垃圾
所有的变量get_defined_vars函数能够看到所有已经定义的变量,那意味着php本身能存储所有变量或已开辟的内存空间,具体在zend_globals.h中struct _zend_executor_globals 中看到
能看到所有的变量,这边变量会被打上视为垃圾的标签
变量本身的定义Zend/zend.h中以看到zval的定义
查看是不是垃圾就看 refcount__gc 是不是为0
PHP中的引用是什么?
引用不是C的指针
引用允许用两个变量来指向同一个内容
引用做的第二件事是用引用传递变量
引用做的第三件事是引用返回
第二步.清除垃圾
找到refcount = 0的就清除,并回收内存(5.2以及以前版本)PHP5.3版本中采用了引用计数系统中的同步周期回收(Concurrent Cycle Collection in Reference Counted Systems)算法来清除 , 基本规则是这样的 ,如果引用技术在+1 ,说明变量再用,不是垃圾,如果引用技术本身为0,那就是垃圾,需要被删除, 如果引用计数-1 其为非0 的时候 将其放到某一区块标记为疑似垃圾,然后对其做很多的模拟操作,最后找到真正的垃圾(为了解决自调用$a=array(1);$a[]=&a这样的垃圾)
当我们存储的疑似垃圾的区域满了的时候,就会被执行清除垃圾的操作,前提是开启了垃圾回收机制,当然,默认是打开的php.ini 设置允许你修改它:zend.enable_gc
修改配置zend.enable_gc ,也能通过分别调用gc_enable() 和 gc_disable()函数来打开和关闭垃圾回收机制。调用这些函数,与修改配置项来打开或关闭垃圾回收机制的效果是一样的。你还能调用gc_collect_cycles()函数达到这个目的。它能强制执行周期回收。
Last updated