2013-08-30 157 views
4

我有一個運行無限長(無限主事件循環)處理來自Twitter的鳴叫傳入的流,並將其存儲到MySQL的PHP​​腳本。但是,我似乎無法控制其內存使用情況。我發現3種方式來衡量內存使用:解決PHP內存泄漏

  • memory_get_usage() - 約4.0 MB
  • memory_get_usage(true)報告 - 報告約7.5 MB
  • exec("ps -o rss -p " . getmypid(), $memOutput); - 報告線性增加的數量快速增長到數百MB在60分鐘或更短的時間內,並繼續吞噬內存,直到腳本被強行終止。

我的問題:

1)什麼是這三個措施之間的實際差別?

但主要是:

2)什麼意思,如果前兩個是相對恆定的,但第三個方法是瘋狂了這樣的控制?

FWIW,我使用PHP 5.3與Zend框架1.x和很多Zend_Db的活動。腳本在CLI SAPI下運行。 Zend_Db_Profiler沒有被使用。我還有第二個無限制運行的腳本,它根本不使用數據庫,並且內存使用情況不變。因此,它似乎是與數據庫相關的,也許是MySQL擴展我的PHP安裝使用,也可能Zend_Db的。我已經在我自己的代碼中不厭其煩地避免不小心緩存的對象,雖然我還沒有與Zend的代碼本身做到了這一點。

我試過讓腳本調用gc_enable(),並定期運行gc_collect_cycles(),但這沒有幫助。

任何想法?

編輯我打算只要我可以分析這個代碼,但同時我也注意到,即使我的腳本不碰DB也被泄漏內存。但是他們的速度要慢得多,只有在幾天的時間內比較內存使用情況纔會顯現出來。

+1

在不需要對象之後,爲了回收內存,您已經採取了哪些步驟? –

+1

首先,我通過使用數組來瞬間存儲數據,從而避免使用對象。但關於對象(比如Zend_Db返回的錶行),我沒有做任何特殊的事情來回收它們的內存。我的理解是,當它們超出範圍(即方法結束時),並且不再引用這些對象時,它們便有資格通過PHP的垃圾回收進行回收。我不保留任何引用。但我意識到Zend_Db可能是。 – curtisdf

回答

2

好,因爲你需要做的剖析自己,我不能指向你確切的答案在這裏。從你所說的看來,Zend的數據庫層看起來很不錯,但除非你對此進行簡要描述,否則你無法確定。 ;)

在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」工具 - 它

提供的所有信息Cachegrind,加上關於調用圖的額外信息

這將創建一個callgrind.out文件或一組我不記得的文件。 反正你現在可以使用Kcachegrind可視化所收集的信息:

kcachegrind callgrind.out 

,你會看到沒有來電的可視化和存儲您的應用程序的某一部分使用的百分比。喜歡的東西: Wordpress memory profile

您也可以嘗試一些在Valgrind的套件一樣Memcheck其他工具來查看

所有讀取和存儲器的寫入和調用malloc /新/免費/刪除

我第一次瞭解Valgrind時試圖剖析我的Linux服務器。然後我研究了一下,結果發現它是一個非常好的工具來分析PHP應用程序......有a very good talk on this here。我使用了一些例子。一探究竟!

並且在你分析你的應用程序後,請回來一些關於它是什麼的信息,或者你看到了什麼等。我將會非常有趣地分析這個。希望這有助於。 ;)

編輯: 我現在記得我錯過了一些東西。 :D 您也可以嘗試使用APD這是一個zend擴展和could also provide useful information。我沒有親自使用過它,但互聯網上有一些很好的例子。

另一個選項是Xhprof - 分層分析器。你可以用這個來gather different metrics。最後應該使用這些工具的組合。如何和爲什麼取決於你。

+1

感謝鮑里斯拉夫的指點。我沒有機會嘗試他們,但是當我有機會時我會。同時我重寫了我的腳本,因此與數據庫相關的部分被稱爲單獨的短暫進程。這有效地解決了內存問題。 – curtisdf

+0

PHP的用戶空間內存使用函數顯示穩定和可預測的值,但仍然令人費解,而只有外部進程顯示的內存使用情況(例如命令行中的「ps」)纔是失控的。這讓我覺得它可能根本不是用戶登陸的PHP代碼,但也許是PHP或我正在使用的一些擴展的較低級別問題。使用您提到的工具來分析代碼會非常有趣。 – curtisdf

+0

@curtisdf確實如此。描述這一點將是非常有趣的。 你願意分享數據嗎?它不會包含任何代碼。它也可能真的是一些外部實體。 無論如何,PHP是一種腳本語言,由於其設計,長時間運行的腳本一直是個問題。 其他要嘗試的事情之一是「異步PHP」 - [作爲示例反應](http://reactphp.org/)。它可能是基於事件的長時間運行腳本的解決方案。 –