2012-08-30 53 views
7

我有一個程序,接受來自套接字的數據,做一些質量控制,並配合其他條件,然後寫出一個命名管道。我運行了valgrind並修復了原來存在的所有內存泄漏。然後,我在一個系統上創建了一個「演示」環境,在該系統中,我運行了32個此程序的實例,每個實例都提供唯一數據,並且每個都輸出到它自己的管道中。我們測試了它,一切看起來都很好。然後,我試圖通過提高數據發送速率來進行壓力測試,並且事情看起來不錯,但是我的程序一直在消耗越來越多的內存,直到我沒有資源。如何追查內存泄漏valgrind說不存在?

我轉向valgrind並運行完全相同的設置,除了每個使用leak-check = full的valgrind運行的程序。發生了一些奇怪的事情。首先,內存確實泄漏,但僅限於每個程序佔用了我內存的0.9%(以前最大的內存佔用了我內存的6%)。由於valgrind運行的程序的CPU成本高漲,而且我現在處於100%cpu並且負載平均水平很高,所以可能缺少可用的CPU會導致程序運行緩慢,從而導致泄漏時間過長。當我嘗試停止這些程序時,valgrind顯示沒有直接的內存泄漏,它顯示了一些潛在的內存泄漏,但我檢查了它們,我不認爲它們中的任何一個代表真正的內存泄漏;除此之外,當程序消耗超過100 MB時,可能的內存泄漏只顯示爲幾千字節。 valgrind報告的可訪問(未泄漏)內存也位於KB範圍內,因此valgrind似乎認爲我的程序正在佔用Top說他們正在使用的內存的一小部分。

我跑了一些其他的測試,並得到奇怪的結果。一個單獨的程序,甚至以三倍的速度運行,我的原始內存泄漏被檢測到,似乎從未消耗多於0.9%的內存,兩個程序分別泄漏1.9和1.3%內存,但沒有更多內存,就好像內存泄露的數量以及泄漏的速度在某種程度上取決於我的程序一次運行多少個實例;這是毫無意義的,每個實例應該100%獨立於其他實例。

我還發現,如果我運行的只有一個實例運行在valgrind valgrinded實例(這是一個字,如果我說這是!)泄漏內存的實例只有一個實例,但速度比在valgrind之外運行的速度慢。 Valgrind實例仍然會說我沒有直接泄漏,並且報告的內存消耗少得多,然後Top節目。

對於可能導致此結果的原因以及valgrind拒絕意識到內存泄漏的原因,我很困惑。我認爲它可能是一個外部庫,但我沒有真正使用任何外部庫;只是基本的C++函數/對象。我也認爲它可能是寫入輸出管道的數據,導致緩衝區無限增長,但1)應該有一個上限,這樣的緩衝區可以增長,2)一旦內存泄漏,如果我丟棄數據輸入速率降低到內存不再消耗,而是慢慢回落到合理的數量。

任何人都可以給我一個暗示我應該從哪裏看?我完全被難住爲什麼內存是這樣表現的。

謝謝。

+2

你確定它是一個泄漏,而不僅僅是你的程序收集內存的一部分?你嘗試過地塊嗎? – PlasmaHH

+0

我自己也遇到了類似的問題(雖然不像古怪),我對任何反饋都很感興趣。一個建議:你能澄清你正在使用的操作系統/版本嗎?我認爲這是一個Linux發行版。 –

+0

Valgrind在沙箱中運行您的程序並執行大量的處理。您應該預計它會有比使用valgrind的相同應用程序更高的CPU使用率和更低的性能。我會考慮在壓力測試過程中,程序是否會創建額外的緩衝區來保存無法進入管道的數據,並且該數據正在增長(不泄漏,只是隨着您無法保持速度而增長)。 –

回答

1

這聽起來像是我最近遇到的問題。

如果您的程序接受數據並在內部進行緩衝而沒有任何限制,那麼它可能比讀取和緩衝數據的速度更快。在這種情況下,內存的使用將繼續增加而沒有限制。

您運行的程序實例越多,每個實例的運行速度越慢,緩衝區的速度也會越快。

這可能是也可能不是你的問題,但沒有更多的信息,這是我能做的最好的。

+0

這是最準確的。我假設每x秒輸出一次數據(由配置文件混淆)。但由於存在一個錯誤,存儲我超時時間的計數器在啓動時不斷增加,因此我存儲了一分鐘的數據。對系統造成的額外壓力導致了在啓動時增加我的超時計數器的錯誤。我想感謝Plasma提到的地塊讓我朝着正確的方向前進。我以爲memcheck告訴我,沒有太多的內存使用,所以我沒有看內存使用;我很可能誤讀了memcheck。 – dsollen

2

你應該首先尋找軟泄漏。它發生在某些靜態或單例逐漸增加緩衝區或容器並收集垃圾時。從技術上講,這不是泄漏,但其影響同樣糟糕。

1

我可以建議你試試MemoryScape嗎?這個工具在內存泄漏檢測方面做得非常好。這不是免費的,但考慮到花費的時間和精力,這是值得嘗試的。