我有約六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解析器。
你用什麼gem來解析輸入JSON?您是否使用C擴展的其他寶石?這聽起來像你的描述(內存使用量增長,但Ruby對象的數量是不變的),就像你可能從具有C擴展的gem泄漏一樣(例如,一些gem分配的內存不用於存儲Ruby對象,從來沒有釋放它)。 – grumbler
也有可能你有一個純粹的Ruby'泄漏',你需要重複變異一個對象,並在不分配新對象的情況下增大它的大小。例如,反覆附加到Ruby字符串會導致它不斷消耗更多內存,而不會碰撞您的對象數量。 – grumbler
@grumbler哦好點。我延長了我的問題。我使用Yajl進行JSON解析,這確實是一個C綁定。從來沒有想過這個。 –