php - 解决 PHP 内存泄漏

标签 php mysql zend-framework memory-leaks

我有一个无限长运行的 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 的 DB 层,但是除非你对此进行分析,否则你无法确定。 ;)

在 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

您将看不到调用的可视化以及应用程序特定部分使用的内存百分比。就像是: Wordpress memory profile

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

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

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

在您介绍您的应用程序之后,请返回有关它是什么的信息,或者您看到了什么等等。我将很乐意对此进行分析。希望这有所帮助。 ;)

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

另一个选项是 Xhprof - 层次分析器。你可以用它来 gather different metrics .最后应该结合使用这些工具。如何以及为什么取决于您。

关于php - 解决 PHP 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18524984/

相关文章:

php - Zend_Navigation 加载失败

php - 定期检查从 Laravel 中的第 3 方应用程序发布的数据

php - 在网页中提供文本文件的内容

mysql 在插入时创建触发器使用 where 条件不起作用进行更新

php - 是否可以使用 PHP PDO 使用第一个表中的列从第二个表中获取数据?

sql - ms-access:从另一个查询中选择

php - Zend_Reflection 无法获取某些类的文档 block

php - 如何将多个文件上传名称保存到数据库?

linux - 无法将元数据保存到 metadataCache

php - 在 zend 中,如何正确打印 mysql 查询?