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()这些都没有减少内存使用量.
我不知道如何强制释放所有内存.
我在这里的答案中编写我以前的评论.这并不能完全解释如何释放已分配的内存,但会引导您通过一种方式来发现应用程序中的内容.有了它,您可以优化代码.
查找内存使用瓶颈通常是一项具有挑战性的任务.您可以从查看与I/O相关的调用开始,例如数据库查询,文件访问甚至网络.除了增加执行时间之外,有时这些操作可以分配一些内存.
如果您已经从I/O操作返回的资源中清除了内存,并且没有注意到分配的内存大幅减少,则下一步可能是使用Blackfire(https://blackfire.io/)等工具来分析您的应用程序.
Blackfire将为您提供每个函数调用的详细视图及其有关内存,CPU和执行时间的统计信息.使用该数据,可以检查哪些操作正在分配过多的内存.当您将鼠标指针放在通话详细信息中的内存条上时,可以找到此信息,如下所示:http://i.imgur.com/762mWmF.png
在对该主题进行了大量研究之后,我终于确信,没有任何方法可以手动强制释放内存或强制破坏对象。
但是,帮助我降低内存使用量(绝对不可能防止无限的内存堆栈)的一件事是认识到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,数据库访问和内存缓存的功能)。