当前位置: 首页 > 后端技术 > PHP

PHP中垃圾回收相关函数

时间:2023-03-29 20:04:22 PHP

我们之前学习过PHP中引用计数和垃圾回收机制的概念。这些内容理论性很强,也是很常见的面试内容。今天介绍的是关于垃圾回收的一些具体函数。前面两篇介绍文章,可以到文末查看。下面说说循环引用和循环引用的强制清理。为什么要强调“循环引用”?其实默认情况下,当我们直接unset()一个没有被其他变量引用的变量时,这个变量的引用计数就会变成0。这时候PHP默认的垃圾回收机制会直接清除这个变量。例如:$a=newstdClass;$b=新标准类;$c=新标准类;echomemory_get_usage(),PHP_EOL;//706528未设置($a);echomemory_get_usage(),PHP_EOL;//706488gc_collect_cycles();echomemory_get_usage(),PHP_EOL;//706488从上面的代码可以看出,我们unset()掉$a之后,直接减少了内存。但是,如果存在循环引用,那么简单的unset()将不起作用。D类{public$d;}$d=newD;$d->d=$d;echomemory_get_usage(),PHP_EOL;//706544unset($d);echomemory_get_usage(),PHP_EOL;//706544gc_collect_cycles();echomemory_get_usage(),PHP_EOL;//706488在这段代码中,我们对\$d进行了简单的循环引用赋值。使用unset()后,内存没有变化。此时只能使用gc_collect_cycles()函数进行强制循环引用清理,清除$d中的无效循环引用。没错,这一段的重点是gc_collect_cycles()函数。一般情况下,它不会对普通变量引用产生任何清理作用。当然,对于普通变量,我们可以直接unset()它们。它的主要作用是清理循环引用。之前我们了解到,循环引用计数会有根缓冲区。通常,默认情况下,它可以容纳10,000个可能的待清理根。gc_collect_cycles()的作用是直接清理,不用等rootbuffer满(个人理解)。关于本次垃圾回收算法的内容请移步:PHP垃圾回收机制的一些粗浅认识其实大多数情况下,我们不需要关注PHP的垃圾回收问题,也就是说,我们不不需要手动调用gc_collect_cycles()函数。PHP-FPM会在每次调用完成后直接整体释放,执行一个简单的CLI脚本后全部释放。没错,正常情况下,PHP执行一次就会把内容全部销毁,内存垃圾自然就消失了。但是在执行长期守护脚本,或者使用常驻进程框架(Swoole)时,还是需要注意是否存在循环引用问题。因为这种程序一直在运行,如果有大量的循环引用对象,可能会造成内存泄漏。开启、关闭和查看循环引用垃圾回收状态gc_disable();echogc_enabled(),PHP_EOL;//gc_enable();echogc_enabled(),PHP_EOL;//1很简单的三个函数,gc_disable()是“停止使用循环引用收集器”,gc_enable()是“启用循环引用收集器”,gc_enabled()是检查当前循环引用收集器是否启用。强制回收Zend引擎内存管理器使用的内存gc_mem_caches()官网和网上没有详细介绍,但是从定义上看,它的主要作用是回收Zend引擎内存使用的内存PHP底层的管理器。这个大家好理解,平时也没有用过。获取垃圾收集器信息$e=newstdClass;for($i=100;$i>0;$i--){$e->list[]=$e;}unset($e);gc_collect_cycles();var_dump(gc_status());//array(4){//["runs"]=>int(1)//["collected"]=>int(2)//["threshold"]=>int(10001)//["roots"]=>int(0)//}我们还是做一个循环引用对象,然后通过gc_status()查看当前垃圾回收器中循环引用的状态。从返回的内容可以看出,runs跑了1,collectedcollected2,threshold是10001,roots可能已经没了(已经回收了)。这个功能可以在测试环境中检查代码的运行情况,看看我们的代码中是否存在异常的循环引用。当然,上面的解释只是个人的猜测,因为这方面的资料真的很少。所以也希望对这方面有深入研究的高手们能够留言指点!!测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202005/source/PHP%E4%B8%AD%E7%9A%84%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E7%9B%B8%E5%85%B3%E5%87%BD%E6%95%B0.php参考文档:PHP参考是什么意思数数?对PHP垃圾回收机制的一些粗浅了解https://www.php.net/manual/zh/function.gc-collect-cycles.phphttps://www.php.net/manual/zh/function.gc-disable。phphttps://www.php.net/manual/zh/function.gc-enable.phphttps://www.php.net/manual/zh/function.gc-enabled.phphttps://www.php.net/manual/zh/function.gc-mem-caches.phphttps://www.php.net/manual/zh/function.gc-status.php============每个媒体平台都可以搜索【硬核项目经理】