我有一个PHP脚本无限期地运行(无限主事件循环)处理来自Twitter的传入推文流并将它们存储到MySQL。但是,我似乎无法控制其内存使用量。我找到了三种测量内存使用的方法:
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()
,但这没有用。
有什么想法吗?
编辑 我打算尽快剖析这段代码,但同时我注意到即使我的脚本没有触及数据库,也会泄漏记忆。但是他们这样做的速度要慢得多,只有在比较几天的内存使用情况时才会变得明显。
答案 0 :(得分:2)
嗯,我不能指出你在这里的确切答案,因为你需要自己进行分析。根据你的说法,它似乎指向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'工具 -
提供Cachegrind所做的所有信息,以及有关调用图的额外信息
这将创建一个callgrind.out
文件或一组我不记得的文件。
无论如何,您现在可以使用Kcachegrind来显示收集的信息:
kcachegrind callgrind.out
您将看不到调用的可视化以及应用的某个部分使用的内存百分比。就像是:
您还可以尝试使用Valgrind套件中的其他工具,例如Memcheck来查看
内存的所有读写和对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。最后,应该使用这些工具的组合。怎么以及为什么由你决定。