解决PHP内存泄漏 [英] Solving PHP memory leaks

查看:272
本文介绍了解决PHP内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个PHP脚本,它无限期运行(无限主事件循环),处理来自Twitter的传入推文流并将其存储到MySQL.但是,我似乎无法控制其内存使用情况.我发现了三种测量内存使用情况的方法:

I have a PHP script that runs indefinitely long (infinite main event loop) processing a stream of incoming tweets from Twitter and storing them to MySQL. However, I can't seem to get its memory usage under control. I've found 3 ways to measure memory usage:

  • memory_get_usage()-报告约4.0 MB
  • memory_get_usage(true)-报告约为7.5 MB
  • exec("ps -o rss -p " . getmypid(), $memOutput);-报告线性增加的数字,该数字在60分钟或更短的时间内迅速增长到数百MB,并继续消耗内存,直到脚本被强制终止.
  • memory_get_usage() - Reports about 4.0 MB
  • memory_get_usage(true) - Reports about 7.5 MB
  • exec("ps -o rss -p " . getmypid(), $memOutput); - Reports a linearly increasing number that quickly grows into the hundreds of MB in 60 minutes or less, and continues eating up memory until the script is forcibly terminated.

我的问题:

1)这三种措施之间的实际区别是什么?

1) What's the practical difference between these three measures?

但主要是:

2)如果前两个相对恒定,那是什么意思呢?但是第3种方法却完全失去了控制力?

2) What does it mean if the first two are relatively constant, but the 3rd method is wildly out of control like this?

FWIW,我将PHP 5.3与Zend Framework 1.x和许多Zend_Db活动一起使用.脚本在CLI SAPI下运行.没有使用Zend_Db_Profiler.我还有第二个无限运行的脚本,它根本不使用数据库,并且内存使用情况是恒定的.因此,这似乎与数据库有关,也许是我的PHP安装程序正在使用的MySQL扩展,或者也许是Zend_Db.尽管我还没有使用Zend的代码本身来做到这一点,但我还是在自己的代码中竭尽全力,避免了漫不经心地缓存对象.

FWIW, I'm using PHP 5.3 with Zend Framework 1.x and a lot of Zend_Db activity. Script runs under the CLI SAPI. Zend_Db_Profiler is not being used. I also have a second infinitely-running script that doesn't use the database at all, and memory usage is constant. So it seems to be database-related, perhaps the MySQL extension my PHP setup is using, or maybe Zend_Db. I've taken great pains within my own code to avoid caching objects carelessly, although I haven't done this with Zend's code itself.

我尝试使脚本调用gc_enable(),并定期运行gc_collect_cycles(),但这无济于事.

I've tried making my script call gc_enable(), and running gc_collect_cycles() periodically, but this doesn't help.

有什么想法吗?

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

Edit I intend to profile this code as soon as I can, but meanwhile I've noticed that even my scripts that don't touch the DB are also leaking memory. But they do so at a much slower rate that only becomes apparent when comparing memory usage over the course of several days.

推荐答案

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

Well I cannot point you to the exact answer here because you need to do the profiling yourself. From what you're saying it seems to point Zend's DB layer, however you cannot be sure unless you profile this. ;)

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

On UNIX/Linux (and I hope you are running PHP the right way - the UNIX/Linux way:D) there are some very useful tools for profiling such apps on the system level and checking instantiation and memory consumption within the PHP app. You can use Valgrind to get some info, something like:

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

请注意,Valgrind是工具套件,这里我们使用的是'callgrind '工具-

Note that Valgrind is a suite of tools and here we're using the 'callgrind' tool - it

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

provides all the information that Cachegrind does, plus extra information about callgraphs

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

This will create a callgrind.out file or a set of them I cannot remember. Anyway you can now use Kcachegrind to visualize the gathered information:

kcachegrind callgrind.out

您将看不到呼叫的可视化以及应用程序某些部分使用的内存百分比.就像是:

you will no see a visualization of calls and the percentage of memory a certain part of your app uses. Something like:

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

You can also try some of the other tools in the Valgrind suite like Memcheck to see

所有内存读写操作以及对malloc/new/free/delete的调用

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

在尝试配置我的Linux服务器时,我首先了解了Valgrind.然后我研究了一下,结果发现它是一个很好的配置PHP应用程序的工具...其中有

I first learnt about Valgrind when trying to profile my Linux server. Then I researched a bit and it turned out that it is a very good tool to profile PHP apps... There is a very good talk on this here. I used some of the examples from there. Check it out!

在对您的应用程序进行配置之后,请返回有关它是什么或您看到的内容等的信息.对此我将非常有兴趣进行分析.希望这对您有所帮助. ;)

And after you profile your app, please come back with information on what was it, or what do you see and etc. I will be very interesting to analyze this. Hope this helped. ;)

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

I now recall that I missed some stuff. :D You can also try using APD wich is a zend extension and could also provide useful information. I haven't personally used it but there are some good examples on the Internet.

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

Another option is Xhprof - the Hierarchical Profiler. You can use this to gather different metrics. In the end a combination of these tools should be used. How and why is up to you.

这篇关于解决PHP内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆