【发布时间】:2013-09-02 17:10:26
【问题描述】:
我有一个运行无限长的 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 返回的表行),我没有做任何特别的事情来回收它们的内存。我的理解是,当它们超出范围时(即方法结束时),并且不再保留对这些对象的引用时,它们就有资格通过 PHP 的垃圾收集进行回收。我没有保留任何参考资料。但我意识到 Zend_Db 可能是。
标签: php mysql zend-framework memory-leaks