php 官方版本 https://www.php.net/manual/zh/features.gc.php 仅针对5.3 新增的gc
易懂版本 https://www.cnblogs.com/xuxubaobao/p/10840176.html
以下大部分是摘抄,如果想详细了解,建议点击上面的两个链接。
说明:每个php变量存在一个叫"zval"的变量容器中。一个zval变量容器,除了包含变量的类型和值,还包括两个字节的额外信息。第一个是"is_ref",是个bool值,用来标识这个变量是否是属于引用集合(reference set)。通过这个字节,php引擎才能把普通变量和引用变量区分开来,由于php允许用户通过使用&来使用自定义引用,zval变量容器中还有一个内部引用计数机制,来优化内存使用。第二个额外字节是"refcount",用以表示指向这个zval变量容器的变量(也称符号即symbol)个数。
重要:
当一个zval在被unset的时候、或者从一个函数中运行完毕出来(就是局部变量)的时候等等很多地方,都会产生zval与zend_value发生断开的行为,这个时候zend引擎需要检测的就是zend_value的refcount是否为0,如果为0,则直接KO free空出内容来。如果zend_value的recount不为0(废话一定是大于0),这个value不能被释放,但是也不代表这个zend_value是清白的,因为此zend_value依然可能是个垃圾。
什么样的情况会导致zend_value的refcount不为0,但是这个zend_value却是个垃圾呢?PHP7种两种情况:
$arr = [ 1 ];
$arr[] = &$arr;
unset( $arr );
这种情况下,zend_value不会能释放,但也不能放过它,不然一定会产生内存泄漏,所以这会儿zend_value会被扔到一个叫做垃圾回收堆中,然后zend引擎会依次对垃圾回收堆中的这些zend_value进行二次检测,检测是不是由于上述两种情况造成的refcount为1但是自身却确实没有人再用了,如果一旦确定是上述两种情况造成的,那么就会将zend_value彻底抹掉释放内存。
目前,zend.enble_gc 是默认打开的,也能通过分别调用gc_enable() 和 gc_disable()函数来打开和关闭垃圾回收机制。调用这些函数,与修改配置项来打开或关闭垃圾回收机制的效果是一样的。即使在可能根缓冲区还没满时,也能强制执行周期回收。你能调用gc_collect_cycles()函数达到这个目的。这个函数将返回使用这个算法回收的周期数。
这个东西虽说用处不大,但是在结束使用大的变量时,使用unset() ,清理以下内存还是有点儿用的。