2011-07-01 51 views
7

我有一個大型的長時間運行的服務器,並且數星期以來內存使用率穩步攀升。如何在python中創建不可收集的垃圾?

一般來說,正如下面指出的那樣,泄漏不太可能是我的問題;然而,我還沒有做很多工作,所以我想看看是否有任何泄漏。

在控制檯輸出是棘手的,所以我沒有運行gc.set_debug()。這不是一個大問題,因爲我已經輕鬆地添加了一個API來運行它,然後運行gc.collect(),然後遍歷gc.garbage並通過HTTP將結果發回給我。

我的問題是在短時間內在本地運行它我的gc.garbage總是空的。在部署泄漏之前,我無法測試我的一小部分代碼。

是否有一個微不足道的方法來創建一個無法收集的垃圾,所以我可以測試我的代碼列出了垃圾?

+0

不是答案,但上個月Giovanni Bajo就EuroPython調試內存泄漏發表了精彩的演講。談話視頻在這裏:http://ep2011.europython.eu/conference/talks/debugging-and-profiling-techniques – grifaton

+0

似乎至少需要一顆種子:( – Will

回答

12

終結對象(即,與一個__del__方法對象)是無法收回的(因爲垃圾收集器不知道哪一個爲運行在終結)的任何週期:

>>> class Finalizable: 
...  def __del__(self): pass 
... 
>>> a = Finalizable() 
>>> b = Finalizable() 
>>> a.x = b 
>>> b.x = a 
>>> del a 
>>> del b 
>>> import gc 
>>> gc.collect() 
4 
>>> gc.garbage 
[<__main__.Finalizable instance at 0x1004e0b48>, 
<__main__.Finalizable instance at 0x1004e73f8>] 

但作爲一般的點,除非你習慣使用終結器,否則你的問題似乎不太可能是由於無法收集的垃圾。這更可能是由於活動對象的積累或內存的碎片化(因爲Python使用非移動收集器)。

+0

對不起,但我想創造垃圾只是爲了看在你的上面的例子中,什麼是垃圾?a和b的實例在刪除它們的引用之前?http://www.pythontutor.com/visualize.html#code=class+Finalizable%3A% 0A ++++ DEF + __德爾__(個體)%3A +通%0A%0AA +%3D +可終結()%0AB +%3D +可終結()%0Aa.x +%3D + b%0Ab.x +%3D +一% 0Aprint(id(a))%0Adel + a%0Adel + b&mode = display&cumulative = true&py = 3&curInstr = 9 – BugShotGG

+2

請親自看看:在刪除它們之前,先打印'id(a)'和'id這些id在收集後匹配'id(gc.garbage [0])'和'id(gc.garbage [1])' –

+0

Yup that worked!乾杯! – BugShotGG