关于php:PHP中的垃圾回收相关函数

35次阅读

共计 2573 个字符,预计需要花费 7 分钟才能阅读完成。

之前咱们曾经学习过 PHP 中的援用计数以及垃圾回收机制的概念。这些内容十分偏实践,也是十分常见的面试内容。而明天介绍的则是具体的对于垃圾回收的一些性能函数。对于之前的两篇介绍文章,大家能够到文章底部查看。

再谈循环援用以及强制清理循环援用

咱们为什么要强调“循环援用”呢?其实,在默认状况下,咱们间接 unset() 掉一个没有被其余变量援用的变量时,就会让这个变量的援用计数变为 0。这时,PHP 默认的垃圾回收机制就会间接革除掉这个变量。比方:

$a = new stdClass;
$b = new stdClass;
$c = new stdClass;
echo memory_get_usage(), PHP_EOL; // 706528

unset($a);
echo memory_get_usage(), PHP_EOL; // 706488

gc_collect_cycles();
echo memory_get_usage(), PHP_EOL; // 706488

从下面的代码中能够看出,咱们 unset() 掉 $a 之后,内存间接就缩小了。然而,如果是产生了循环援用的状况,那么简略的进行 unset() 就没有成果了。

class D{public $d;}
$d = new D;
$d->d = $d;
echo memory_get_usage(), PHP_EOL; // 706544

unset($d);
echo memory_get_usage(), PHP_EOL; // 706544

gc_collect_cycles();
echo memory_get_usage(), PHP_EOL; // 706488

在这段代码中,咱们对 \$d 进行了一个简略的循环援用赋值。应用 unset() 后,内存没有发生变化,这时,只能应用 gc_collect_cycles() 函数来进行强制的循环援用清理,能力将 $d 外面的有效循环援用革除掉。

没错,这一段的重点正是 gc_collect_cycles() 这个函数。它在失常状况下对一般的变量援用是不会产生什么清理成果的,当然,对于一般的变量咱们间接 unset() 掉就能够了。它最次要的作用就是针对循环援用的清理。之前咱们学习过,循环援用计数会存在一个 根缓冲区,个别默认状况下它能包容 10000 个待清理的 可能根。而 gc_collect_cycles() 的作用就是不必等这个 根缓冲区 满就间接进行清理(集体了解)。对于这个垃圾回收算法的内容请移步:PHP 垃圾回收机制的一些肤浅了解

其实,大部分状况下咱们是不太须要关注 PHP 的垃圾回收问题的,也就是说,咱们不是很须要手动地去调用这个 gc_collect_cycles() 函数。PHP-FPM 在每次调用实现后会间接整体的开释,简略的一次 CLI 脚本执行完也会全副开释。没错,失常状况下,PHP 一次执行实现之后就会销毁所有的内容,内存垃圾天然也就不存在了。然而,在执行长时间的守护脚本时,或者应用常驻过程的框架(Swoole)时,还是须要留神有没有循环援用的问题。因为这种程序始终运行,如果存在大量循环援用对象时,就有可能导致内存泄露。

开启、敞开及查看循环援用垃圾回收状态

gc_disable();
echo gc_enabled(), PHP_EOL; //
gc_enable();
echo gc_enabled(), PHP_EOL; // 1

很简略的三个函数,gc_disable() 是“停用循环援用收集器”,gc_enable() 是“开启循环援用收集器”,而 gc_enabled() 就是查看以后的循环援用收集器是否开启。

强制回收 Zend 引擎内存管理器应用的内存

gc_mem_caches()

官网及网络上并没有什么具体的介绍,不过从定义来看,它次要的作用就是回收 PHP 底层的 Zend 引擎内存管理器所应用过的内存。这个大家理解下就好,平时也素来没用过。

获取垃圾收集器的信息

$e = new stdClass;
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 个,collected 收集了 2 个,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.php

https://www.php.net/manual/zh/function.gc-disable.php

https://www.php.net/manual/zh/function.gc-enable.php

https://www.php.net/manual/zh/function.gc-enabled.php

https://www.php.net/manual/zh/function.gc-mem-caches.php

https://www.php.net/manual/zh/function.gc-status.php

===========

各自媒体平台均可搜寻【硬核项目经理】

正文完
 0