mcf*_*edr 3 php garbage-collection
我正在编写一个PHP cli程序,该程序是队列系统的辅助进程。
我认为在这种情况下,PHP会不时收集垃圾,并且不会经常达到内存限制。
事实并非如此。
zend.enable_gc = 1归结为这个。您必须通过调用手动触发垃圾收集gc_collect_cycles()。
我写了很多代码来尝试追踪并归结为两个脚本:
这不会崩溃:
for($i = 0;$i < 100;$i++) {
useMemory();
gc_collect_cycles();
}
Run Code Online (Sandbox Code Playgroud)
这崩溃了:
for($i = 0;$i < 100;$i++) {
useMemory();
}
Run Code Online (Sandbox Code Playgroud)
这是在Blackfire上比较这些脚本的链接
如您所见,当您不调用gc_collect_cycles它时,它永远不会发生,并且您达到了内存限制,PHP杀死了自己。
PHP甚至没有利用此机会进行GC本身。在PHP-DEV邮件列表上讨论了其背后的原因,但是基本上归结为__destruct当达到内存限制时如何运行需要内存的方法的复杂性。(也在Bug跟踪器#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;
}
Run Code Online (Sandbox Code Playgroud)