2013-09-24 51 views
26

我有約六Sidekiq工人其中執行JSON爬行。取決於端點的數據集大小,它們在1分鐘和4小時之間完成。特別是,觀看長達4小時的長時間內容,隨着時間的推移,我會看到內存的輕微增加。Sidekiq沒有釋放內存後,工人已經完成

這不是問題,直到我想再次安排相同的工作。內存不會被釋放並堆積起來,直到我碰到Linux OOM Killer,它擺脫了我的Sidekiq過程。

內存泄漏?我看着不同的對象的數量,對象空間:

ObjectSpace.each_object.inject(Hash.new(0)) { |count, o| count[o.class] += 1 } 

是不是真的增加了那裏,散列集合,陣列等保持不變,短期上漲是由垃圾收集器和gc.stat[:count]告訴捲走我,垃圾收集器也在工作。

即使在工人完成後,例如我得到[完成]記錄,並且沒有工作者再忙,內存不會被釋放。這是什麼原因?我能對此做些什麼嗎?寫一個終結器?

唯一的當前解決方案:重新啓動Sidekiq進程。

我在Ruby 2.0.0上使用Ruby MRI。


對於JSON解析我使用Yajl,因此C綁定。我需要它,因爲它似乎是唯一能夠正確實現流式讀寫的快速JSON解析器。

+1

你用什麼gem來解析輸入JSON?您是否使用C擴展的其他寶石?這聽起來像你的描述(內存使用量增長,但Ruby對象的數量是不變的),就像你可能從具有C擴展的gem泄漏一樣(例如,一些gem分配的內存不用於存儲Ruby對象,從來沒有釋放它)。 – grumbler

+4

也有可能你有一個純粹的Ruby'泄漏',你需要重複變異一個對象,並在不分配新對象的情況下增大它的大小。例如,反覆附加到Ruby字符串會導致它不斷消耗更多內存,而不會碰撞您的對象數量。 – grumbler

+1

@grumbler哦好點。我延長了我的問題。我使用Yajl進行JSON解析,這確實是一個C綁定。從來沒有想過這個。 –

回答

8

邁克·佩勒姆誰寫Sidekiq解決了這個位置:http://www.mikeperham.com/2009/05/25/memory-hungry-ruby-daemons/

TL;博士版本: MRI不會給內存回來,你能做的最重要的是控制堆,要做到這一點,建議使用Ruby Enterprise Edition

不知道這有助於什麼,但這是情況 - 直接從馬的嘴裏。

+1

好的指針@digitalextremist +1 – Rohit

+1

這很有趣,謝謝:) –

+9

老線程,我知道,但想知道如果你知道這是否仍然適用於Ruby 2.1並且它是新的GC? –