我正在编写一个 PHP cli 程序,它是队列系统的工作进程。
我假设 PHP 在这种情况下会不时收集垃圾,并且不会经常达到内存限制。
情况似乎并非如此。
笔记
zend.enable_gc = 1
最佳答案
归结为这一点。您必须通过调用 gc_collect_cycles()
手动触发垃圾回收。 .
我已经编写了一堆代码来尝试跟踪它并归结为两个脚本:
这个不会崩溃:
for($i = 0;$i < 100;$i++) {
useMemory();
gc_collect_cycles();
}
这个崩溃了:
for($i = 0;$i < 100;$i++) {
useMemory();
}
这是在 Blackfire 上比较这些脚本的链接
如您所见,当您不调用
gc_collect_cycles
它永远不会发生,并且您达到了内存限制,并且 PHP 会杀死自己。PHP 甚至没有利用这个机会进行 GC 本身。这背后的原因在 PHP-DEV mailing list 上进行了讨论。 , 但基本上归结为如何运行
__destruct
的复杂性达到内存限制时需要内存的方法。 (也在错误跟踪器 #60982 上)。内存使用函数:
这是我用来“浪费”内存的代码,它有目的地创建只能由垃圾收集器清理的循环引用。请注意,如果没有这些循环,一旦对象超出范围,就会通过引用计数来清理它们。
class Big {
private $data;
public function __construct($d = 0) {
for($i = 0;$i< 1024 * 10;$i++) {
$this->$i = chr(rand(97, 122));
}
}
}
function useMemory() {
$a = new Big();
$b = new Big();
$a->b = $b;
$b->a = $a;
}
关于php - PHP 何时在长时间运行的脚本中运行垃圾收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38850391/