要了解PHP的GC垃圾回收机制,至少对PHP内核表示PHP空间的值或者变量要有所了解,不然无法理解。
1.当任何关联到某个变量容器的变量离开它的作用域(比如:函数执行结束),或者对变量调用了函数 unset()时,“refcount”就会减1
2.php-5.3以前循环引用问题
1 2 3 4 |
<?php $a = array( 'one' ); $a[] =&$a; unset($a); |
那么变量 $a 和数组元素 “1” 所指向的变量容器的引用次数减1, 从”2”变成”1”.
问题
尽管不再有某个作用域中的任何符号指向这个结构(就是变量容器),由于数组元素“1”仍然指向数组本身,所以这个zval容器不能被清除。
对PHP应用带来的风险
对于大多数的PHP运行环境(接受请求-处理请求-结束释放),循环引用不会带来多大的风险,因为PHP的进程响应请求之后,ZEND MM会将请求分配的内存全部释放。但是对于复杂业务逻辑,需要PHP进行大量CPU运算和分配内存空间,编码中容易出现循环引用,或者使用PHP写长时间运行的服务进程或者守护进程,这样的内存泄露将会带来很大的风险,有可能将系统资源消耗殆尽,或者服务不可用。
php-5.3之后的解决方案
垃圾的定义:新的GC负责清理的垃圾是指变量的容器zval还存在,但是又没有任何变量名指向此zval。因此GC判断是否为垃圾的一个重要标准是有没有变量名指向变量容器zval。
方案:新的垃圾回收机制就是要解决循环引用或者环形引用的内存泄露问题,php-5.2之前的引用计数,当refcount=0时,仍然进行内存释放即对zval进行free。
如果不想深究新的Zend GC机制,了解上述即可。
想更多深入的了解,参考
PHP新的垃圾回收机制:Zend GC详解