解决PHP内存泄漏问题

我有一个
PHP脚本无限期地运行(无限主事件循环)处理来自Twitter的传入推文流并将它们存储到MySQL.但是,我似乎无法控制其内存使用量.我找到了3种测量内存使用量的方法:

> memory_get_usage() – 报告大约4.0 MB
> memory_get_usage(true) – 报告大约7.5 MB
> exec(“ps -o rss -p”.getmypid(),$memOutput); – 报告线性增加的数字,在60分钟或更短的时间内快速增长到数百MB,并继续占用内存,直到脚本被强制终止.

我的问题:

1)这三项措施之间的实际区别是什么?

但主要是:

2)如果前两个相对恒定,这意味着什么,但第三种方法是如此严重失控?

FWIW,我正在使用PHP 5.3和Zend Framework 1.x以及很多Zend_Db活动.脚本在CLI SAPI下运行. Zend_Db_Profiler未被使用.我还有第二个无限运行的脚本,根本不使用数据库,内存使用量是不变的.所以它似乎与数据库相关,也许是我的PHP设置正在使用的MySQL扩展,或者Zend_Db.我在自己的代码中花了很大的力气,以避免不小心缓存对象,虽然我没有用Zend的代码本身做到这一点.

我已经尝试让我的脚本调用gc_enable(),并定期运行gc_collect_cycles(),但这没有帮助.

有任何想法吗?

编辑我打算尽快剖析这段代码,但同时我注意到即使我的脚本没有触及数据库,也会泄漏内存.但是他们以更慢的速度这样做,只有在比较几天的内存使用情况时才会变得明显.

最佳答案 好吧,我不能指出你在这里的确切答案,因为你需要自己进行分析.根据你的说法,它似乎指向Zend的数据库层,但除非你对此进行分析,否则你无法确定. 😉

在UNIX / Linux上(我希望你以正确的方式运行PHP – UNIX / Linux方式:D)有一些非常有用的工具可以在系统级别上分析这些应用程序,并检查PHP应用程序中的实例化和内存消耗.
  您可以使用Valgrind获取一些信息,例如:

valgrind --tool=callgrind --dump-instr=yes -v --instr-atstart=no /usr/sbin/apache2 -X

请注意,Valgrind是suite of tools,在这里我们使用’callgrind’工具 – 它

provides all the information that Cachegrind does, plus extra information about callgraphs

这将创建一个callgrind.out文件或一组我不记得的文件.
无论如何,您现在可以使用Kcachegrind来显示收集的信息:

kcachegrind callgrind.out

您将看不到调用的可视化以及应用的某个部分使用的内存百分比.就像是:

你也可以试试Valgrind套件中的其他工具,如Memcheck

all reads and writes of memory and calls to malloc/new/free/delete

我在尝试配置我的Linux服务器时首先了解了Valgrind.然后我研究了一下,结果发现它是一个非常好的工具来分析PHP应用程序…有a very good talk on this here.我使用了那里的一些例子.看看这个!

在您分析您的应用程序之后,请回来查看它是什么,或者您看到了什么等信息.我将非常有趣地分析这个.希望这有帮助. 😉

编辑:
  我现在记得我错过了一些东西. :d
您也可以尝试使用APD,这是一个zend扩展和could also provide useful information.我没有亲自使用它,但在互联网上有一些很好的例子.

另一个选项是Xhprof – Hierarchical Profiler.您可以将此用于gather different metrics.最后,应使用这些工具的组合.怎么以及为什么由你决定.

点赞