我有一个在 cron 上运行的 PHP 脚本,最多可能需要 15 分钟才能执行。我定期让它吐出 memory_get_usage() 这样我就可以看到发生了什么。它第一次告诉我我的用法是 10 兆。当脚本完成时,我有 114 兆字节!
PHP 会在脚本运行时进行垃圾回收吗?或者所有这些内存发生了什么?有什么我可以做的来强制垃圾收集。我的脚本正在执行的任务是每晚将几千个节点导入 Drupal。所以它多次做同样的事情。
有什么建议吗?
最佳答案
关键是你unset不需要全局变量时立即使用它们。
您无需为局部变量和对象属性显式调用 unset,因为当函数超出范围或对象被销毁时,它们会被销毁。
PHP 为所有变量保留一个引用计数,并在该引用计数变为零时立即销毁它们(在大多数情况下)。对象有一个内部引用计数,每个变量本身(对象引用)都有一个引用计数。当所有对象引用因为它们的引用计数都为 0 而被销毁时,对象本身将被销毁。示例:
$a = new stdclass; //$a zval refcount 1, object refcount 1
$b = $a; //$a/$b zval refcount 2, object refcount 1
//this forces the zval separation because $b isn't part of the reference set:
$c = &$a; //$a/$c zval refcount 2 (isref), $b 1, object refcount 2
unset($c); //$a zval refcount 1, $b 1, object refcount 2
unset($a); //$b refcount 1, object refcount 1
unset($b); //everything is destroyed
但考虑以下场景:
class A {
public $b;
}
class B {
public $a;
}
$a = new A;
$b = new B;
$a->b = $b;
$b->a = $a;
unset($a); //cannot destroy object $a because $b still references it
unset($b); //cannot destroy object $b because $a still references it
这些循环引用是 PHP 5.3 的垃圾收集器发挥作用的地方。您可以使用 gc_collect_cycles
显式调用垃圾收集器。 .
关于脚本运行时的 php 垃圾回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3110235/