4

我有一个运行无限长的 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()定期运行,但这没有帮助。

有任何想法吗?

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

4

1 回答 1

2

好吧,我无法在这里指出确切的答案,因为您需要自己进行分析。从您所说的看来,它似乎指向 Zend 的 DB 层,但是除非您对此进行分析,否则您无法确定。;)

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

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

请注意,Valgrind 是一套工具,在这里我们使用的是“callgrind”工具——它

提供 Cachegrind 所做的所有信息,以及有关调用图的额外信息

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

kcachegrind callgrind.out

您将看不到调用的可视化以及应用程序的某个部分使用的内存百分比。就像是: WordPress 内存配置文件

您还可以尝试 Valgrind 套件中的其他一些工具,例如Memcheck以查看

所有内存的读取和写入以及对 malloc/new/free/delete 的调用

在尝试分析我的 Linux 服务器时,我第一次了解了 Valgrind。然后我研究了一下,结果发现它是一个非常好的分析 PHP 应用程序的工具……这里有一个很好的讨论。我使用了那里的一些例子。一探究竟!

在你分析你的应用程序之后,请回来提供关于它是什么,或者你看到了什么等等的信息。我会很有趣地分析这个。希望这有帮助。;)

编辑:我现在记得我错过了一些东西。:D 你也可以尝试使用APD,它是一个 zend 扩展,也可以提供有用的信息。我没有亲自使用过,但互联网上有一些很好的例子。

另一个选择是Xhprof - 层次分析器。您可以使用它来收集不同的指标。最后,应该使用这些工具的组合。如何以及为什么取决于您。

于 2013-09-12T07:30:59.300 回答