PHP循环引用问题

PHP循环引用,从字面的意思上来看就是自己引用自己,导致内存无法被回收,出现泄露的问题。这个问题在PHP面试的过程中经常会碰到。

一个循环应用的例子:

<?php
$a = array('val');
$a[] =& $a;
xdebug_debug_zval('a');

//输出
a: (refcount=2, is_ref=1)=array (0 => (refcount=2, is_ref=0)='zval', 1 => (refcount=2, is_ref=1)=...)
//unset($a)

从上面可以看出a的应用已经开始循环,此时我们如果使用unset($a), 那么a这个变量就不可达,内存就无法回收,这段代码如果跑上上千万次,内存泄露就很严重了。

如何解决这个问题?

采用同步回收算法,对一个对象进行unset的时候,判断一下其引用计数是否为0,如果为0就直接释放掉,如果不为零,就将其放入一个双向链表中记录下来,等根缓冲区满了时,就会对其进行垃圾回收。

参考资料:

http://blog.100dos.com/2017/04/07/php-garbage-collection-collect-cycles/

开源疫情API接口
2020年5月关系型数据库DB-Engines排行榜