我的专用服务器拥有32GB的RAM和存储刚爬呀爬的不断和我现在每天重新启动它。 这是我损失的客户和资金。
我有一个很难找到其中内存泄漏。 我能在网上找到的是人说“使用了XDebug”,但我一直没能找到在查找内存泄漏任何Xdebug的教程。 我曾尝试打印memory_get_usage之前和之后的函数调用,但是是正确的方式做到这一点?
我已经运行许多PHP脚本 - 一些参观者,他人cron作业 - 我需要找到哪个(些)人正在泄漏内存,并尽快将其修复,但我甚至不知道如何确定给定功能内存泄漏与否。
我曾尝试打印memory_get_usage函数调用之前和之后,它上升,但随后如果我调用函数不止一次,现在不上去。 有人可以解释这一点,并告诉我,我怎么能简单方便地判断一个PHP函数有内存泄漏?
你可以做各种事情,但首先你应该尽量避免在首位的内存泄漏的创建。
让我澄清一下:PHP是一种脚本语言,它不适合长时间运行的脚本,所以它的内存管理是不是市场上最好的。 但是,为什么呢? 它的目的是在请求级别被调用,所以它的运行规模是相当小的(不超过2 - 3秒)。 一切应放在后台。
我能做到对内存泄漏是什么?
如果你在低于5.4版本,你需要照顾圈引用,因为这些都不是垃圾收集。
如果你需要一个脚本来连续运行,你可能会考虑不同的方法。 不要尝试了while(true)
的实现,但换supervisor
( http://supervisord.org )在你的脚本,并让它结束后,系统会调用。 这样,你做100%肯定你永远不会得到内存泄漏。
你可以使用xdebug
分析您的脚本逐一找出来,那里有很多的内存消耗。
你可以实现一个析构函数来取消所有你引用如果类的任何需求不再。
public function __destruct(){ $this->cleanup(); } public function cleanup() { //cleanup everything from attributes foreach (get_class_vars(__CLASS__) as $clsVar => $_) { unset($this->$clsVar); } //cleanup all objects inside data array if (is_array($this->_data)) { foreach ($this->_data as $value) { if (is_object($value) && method_exists($value, 'cleanUp')) { $value->cleanUp(); } } } }
通读有关垃圾收集的PHP文件http://us3.php.net/manual/en/features.gc.php
避免全局变量,因为这些都是从来没有垃圾收集,必须unset
作了明确规定。 如果您使用的是像ZF或Symfony的一个框架,可能是不可能的,因为如果你这样做你会打破功能。
最后但并非最不重要我想再次强调 ,PHP不适合长时间运行的脚本! 如果你有事情要做,这需要连续运行,你不应该崩溃你的头在PHP中的内存泄漏,而是花时间去学习更复杂的语言如Java或C#的时间。
看看这个PHP扩展: https://github.com/arnaud-lb/php-memory-profiler 。 您将可以在不同的格式转储信息和简单的一些工具,如对其进行分析: 谷歌性能工具 , KCacheGrind或QCacheGrind 。
我发现方法,它工作得很好对我来说:
安装“ PHP-memprof ”推广。 在你可以运行Ubuntu的:
sudo pecl install memprof
安装“ 谷歌- perftools ”。 同样为Ubuntu:
sudo apt-get install google-perftools
添加该代码begining你的脚本:
if (function_exists('memprof_enable')) { memprof_enable(); }
而这个地方和身边是你expexct找到内存泄漏:
if (function_exists("memprof_dump_pprof")) { $time = microtime(true); $f = fopen("/tmp/profile_$time.heap", "w"); memprof_dump_pprof($f); fclose($f); echo "Memory profile dumped. "; }
在我的情况下,它是大周期内的每个100次。
运行google-pprof
比较2内存转储:
google-pprof --web --base=/tmp/profile_17.heap /tmp/profile_18.heap
这将打开这样在浏览器中SVG图像:
你内心的号码和姓名的说明可以找到gperftools文档
PS固定在PHP级别的泄漏并不能保证你有在解释没有内存泄漏。 在我来说,我最终只是在更长的时间重新启动sctipt。
我不是在内存使用方面的专家,但也许这种方法会帮助您检测有问题的脚本:
获取信息:1.使用Apache访问日志文件2.创建您自己的内存使用情况日志文件( http://www.webhostingtalk.com/showthread.php?t=617742 )
检查时的内存使用量上升,并比较apache的访问日志。
这将至少给你的信息的使用是否上升缓慢和持续或者如果它开始在某一个点。
祝好运!