执行后,同一对象中的方法是否释放内存?

时间:2016-10-30 04:18:05

标签: php

我正在尝试调试PHP内存泄漏。根据{{​​3}},PHP在函数结束后释放内存..那么,它对于对象函数是否也有效?

我的对象有以下方法:

function process All(){

    $this->processA(); // intensive array processing - runs fine
    $this->processB(); // intensive array processing - runs fine
    $this->processC(); // intensive array processing - runs fine
    $this->processD(); // intensive array processing - memory leak

}

然后我改为:

function process All(){

    $this->processD(); // intensive array processing - runs fine

}

所以似乎每个功能都堆积在内存上。关于如何释放它的任何想法?

1 个答案:

答案 0 :(得分:1)

首先,澄清术语(以便我们明确说明内存泄漏 时的含义。)

  • 当程序在系统上分配了程序无法访问的内存时,会发生内存泄漏。这根本不是PHP代码的直接结果,因为PHP全权负责为您管理程序的内存。这意味着如果发生内存泄漏,那将是PHP本身( PHP内存管理器)的错误,而不是您可能编写的PHP代码。只有用C语言编写的PHP扩展和PHP内存管理器本身才能泄漏内存。 PHP代码,不能 。我可以向你保证,后者非常罕见,即使不是不可能。

因此,根据此信息,您的PHP代码无法泄漏内存( 期间 )。

可能的意思是说,你要么点击用户定义的PHP memory_limit,要么你的代码在OOM中产生( Out of内存)错误。然而,这并不是人们所说的内存泄漏。因此,将实际的OOM错误与您的问题一起包含在内是非常重要的,以便能够以任何程度的权限解读问题。

因为您指出的答案与释放本地函数变量以及您作为问题提供的代码有关,所以绝对没有提示任何本地函数变量正在被使用,它仍然完全不清楚在哪里分配内存第一名。

如果我不得不猜测,我会说你可能将这个数组存储为对象属性。因此,它在内存中保留在运行时期间对象实例的任何生动引用。

局部变量和实例属性之间的区别在于函数完成后会破坏局部变量。但是,实例属性在销毁它所属的对象实例之前不会被销毁。直到对该对象的最后一次引用被破坏或您自己明确地这样做时才会发生这种情况。

class Foo {

    protected $arr = [];

    public function bar($baz) {
        $this->arr[] = $baz; // object instance property
        $quix = $baz; // local function variable
    }

}

$foo = new Foo;
$foo->bar(1);
$foo->bar(2);
$foo->bar(3); // memory grows

在上面的场景中,局部变量$quix总是在每次方法调用后被销毁(无论你使用的是函数还是方法,它都不会改变,它们与PHP相同)。但是,实例属性$this->arr属于对象实例。因此,PHP无法从内存中自行删除,直到该实例$foo被破坏或脚本结束(隐式破坏所有内存)。