PHP:在循环中有一些内存问题

Ped*_*iro 15 php memory garbage-collection

我有一个类似于以下内容的代码段:

while (true) {
    $myObject = new Class();
    $myOtherObject = $myObject->getSomeOtherObj();
    ...
    $myArray = [1, 2, 3];
    ...
    sleep(1); //Sleep at the end, to save CPU.
}
Run Code Online (Sandbox Code Playgroud)

这个片段应该作为守护进程服务运行,但是我在使用这个工作时遇到了很多麻烦.

问题:每次迭代都会增加进程内存使用量.好像在每次新的迭代中都是新的$myObject中都要实例化,但前一个仍然在内存中分配,等等.

我试过了:

  • unset在循环结束时,所有的变量(右前sleep()).
  • 将所有变量设置为 null.
  • 将它们封装在一个单独的函数中(while (true) { doThis(); })
  • 手动呼叫 gc_collect_cycles()

这些都没有减少内存使用量.

我不知道如何强制释放所有内存.

Gus*_*ube 7

我在这里的答案中编写我以前的评论.这并不能完全解释如何释放已分配的内存,但会引导您通过一种方式来发现应用程序中的内容.有了它,您可以优化代码.

查找内存使用瓶颈通常是一项具有挑战性的任务.您可以从查看与I/O相关的调用开始,例如数据库查询,文件访问甚至网络.除了增加执行时间之外,有时这些操作可以分配一些内存.

如果您已经从I/O操作返回的资源中清除了内存,并且没有注意到分配的内存大幅减少,则下一步可能是使用Blackfire(https://blackfire.io/)等工具来分析您的应用程序.

Blackfire将为您提供每个函数调用的详细视图及其有关内存,CPU和执行时间的统计信息.使用该数据,可以检查哪些操作正在分配过多的内存.当您将鼠标指针放在通话详细信息中的内存条上时,可以找到此信息,如下所示:http://i.imgur.com/762mWmF.png


Ped*_*iro 5

在对该主题进行了大量研究之后,我终于确信,没有任何方法可以手动强制释放内存或强制破坏对象。

但是,帮助我降低内存使用量(绝对不可能防止无限的内存堆栈)的一件事是认识到PHP 中没有循环作用域,并且在切换作用域时发生了垃圾回收。

在C#或Java中,while (...) {}只能在循环中访问在内部创建的变量。这不是PHP的规范。一个$myObject从内部创建的while指令是在您的整个应用程序访问。

这意味着所提供的代码片段将更好地呈现为:

while (true) {
    myFunc();
}

function myFunc()
{
    $myObject = new Class();
    $myOtherObject = $myObject->getSomeOtherObj();
    ...
    $myArray = [1, 2, 3];
    ...
    sleep(1); //Sleep at the end, to save CPU.
}
Run Code Online (Sandbox Code Playgroud)

将逻辑封装在函数中会强制更改范围,这意味着将在每次迭代时调用垃圾回收器。这已经不是解决我的问题,但它会降低,我的RAM使用。

我从这种经验中学到的是,PHP可能不适合此特定项目要求。我需要对内存的更多控制,PHP不提供对创建/销毁对象的任何控制。某些本机功能无法正确释放内存(特别是那些进行I / O,数据库访问和内存缓存的功能)。