2011-08-23 274 views
3

我爲一些其他項目製作簡單的IRC bot時,一直在玩PHP socket,但是我注意到在幾個小時後它會吃掉所有內存可用。fgets中的內存泄漏

我一直在使用memory_get_usage()進行一些調試,並確保我清空了我在循環中使用的所有變量後,導致內存使用增加的唯一原因是「fgets()」,而且我無法似乎弄清楚爲什麼它不會在使用它之後釋放它的內存。

任何想法,我一直在做什麼錯?

Psudo代碼:

$this->socket = stream_socket_client(server, port); 
stream_set_blocking($this->socket, 0); 
stream_set_timeout($this->socket, 600); 

while(true) { 
    usleep(500000); 
    $data = fgets($this->socket, 8192); 
    *work with data if strlen > 0* 
    $data = null; 
} 

請注意,我有殘疾阻塞,這樣,當有上是看的頻道沒有活動的機器人可以做一些後臺任務均勻。

內存使用之前,並呼籲與fgets(相同的結果與stream_get_line)後:

int(959504) 
string(0) "" //Data returned from gets 
int(967736) 

請注意,我針對SSL服務器的測試,這會是某種SSL「溢出」的?

或者,如果你想看看整個代碼自己:https://github.com/Ueland/VikingBot

+0

不希望flock()在鎖定時被阻止 – Jason

回答

1

根據https://bugs.php.net/bug.php?id=38962它這是在一個特定的PHP 5.2.6版本複製錯誤。因此,如果您使用更高版本,則可以報告有關您的發現的信息:)

+0

您指向'00?中PHP4.0beta3報告的錯誤嗎?沒有提及的PHP 5.2.6? –

+0

@ Marc-b對不起,從另一個標籤鏈接:) –

+0

奇怪的部分是,如果我嘗試運行bug測試用例,它不會給我這個問題,即使我做一個簡單地讀取/ dev/urandom的新腳本。但只要我嘗試從IRC服務器中獲取數據,每個fgets的內存使用量就會增加160個字節。 – Ueland

0

只需將變量設置爲null,不會釋放先前數據使用的內存。它只是從變量中斷開數據。在將來的某個時候,PHP垃圾收集器可能會啓動並實際釋放內存,但不能保證這樣做。垃圾收集是一個非常昂貴的操作,CPU使用方式明智,PHP不會運行GC,除非它絕對必須。通常這是當內存使用量接近memory_limit設置。

您可以嘗試通過gc_collect_cycles()

+0

我甚至試圖手動強制GC,甚至在空閒內存變低時卻添加了對gc_collect_cycles()的自動調用,但沒有骰子。無論如何,記憶都會耗盡。代碼中的所有空值都是我努力確保所有可以做到記憶明智的結果。 – Ueland

0

使用stream_get_line強制GC的run(),而不是與fgets()的

+0

fgets和stream_get_line都給我每次給他打電話時額外的160bytes的數據,他們沒有數據要返回。 – Ueland

0

想通了最後。我意識到,不是做一個「while(true)」,而是使用一個只在完成時才調用自己的函數,因此保留了自己的參考。不知道爲什麼我現在沒有注意到它,但至少現在每一輪的內存使用保持不變。 ;)

感謝您的所有建議!