PHP的内存使用情况与类

时间:2013-12-19 10:28:45

标签: php oop memory memory-leaks

我试图了解unset()如何使用类及其属性。我写了一个小测试来查看内存使用情况。

class B {}
class A {
    private $b;
    public function __construct() {
        $this->b = new B;
    }
    public function __destruct() {
        unset($this->b);
    }
}

echo memory_get_usage() . '<br/>';

$a = [];
for ($i = 0; $i < 5000; $i++) {
    $a[$i] = new A;
}

echo memory_get_usage() . '<br/>';

for ($i = 0; $i < 5000; $i++) {
    $a[$i]->__destruct();
    unset($a[$i]);
}
unset($a);

echo memory_get_usage() . '<br/>';

我所期待的是最后一次内存使用应该与第一次内存使用类似。但它要高得多:

236184 (before)
2845320 (peak)
1219432 (after)

我真的不明白这一切是如何运作的。谢谢你的帮助!

注意:我试图为__destruct使用另一个名称(我们永远不知道),但这不会改变任何内容。

根据下面的一些评论,我尝试了memory_get_usage(true);结果如下:

262144 (before)
3145728 (peak)
2359296 (after)

1 个答案:

答案 0 :(得分:2)

IN PHP unset()正如它的名字所说 - 取消设置一个变量。它不会强制立即释放内存。 PHP的垃圾收集器会在看到拟合时执行它 - 尽快意图,因为无论如何都不需要那些CPU周期,或者在脚本耗尽内存之前,无论先发生什么。

如果你正在做$ whatever = null;那么你正在重写变量的数据。您可能会更快地释放/缩小内存,但它可能会更快地从真正需要它们的代码中窃取CPU周期,从而导致更长的总体执行时间。

请注意,在php5.3之前,如果循环引用中有两个对象,例如在父子关系中,则在父对象上调用unset()将不会释放用于子对象中父引用的内存。 (当父对象被垃圾收集时,也不会释放内存。)bug 33595