2014-10-31 53 views

回答

0

簡而言之:它的確如此,動態創建的函數與運行時創建的任何其他Python對象一樣創建。

較長的答案:對於垃圾收集器管理的資源,例如不綁定到外部資源的對象,Python和PyGTK將正確處理未使用的對象。對於外部資源,例如打開的文件或正在運行的線程,您需要採取措施確保其正確清理。爲了準確回答你的問題,看到具體的代碼會很有用。在一般情況下,下面的事情適用於Python和GTK:

  • Python對象,包括動態創建功能,將被釋放,他們可以不再用Python到達後的一段時間。在某些情況下,在對象變得無法訪問後立即發生解除分配(如果對象不參與引用循環),而在其他情況下,您必須等待垃圾收集器踢入。

  • 銷燬小部件會導致GTK資源該小部件要立即清除。對象本身可以保持活着。通過小部件可訪問的回調應立即解除引用,並且,如果沒有其他任何東西從Python中保留,它們很快就會被釋放。

可以使用弱引用類型從weakref模塊來進行測試。例如:

>>> import gtk 
>>> 
>>> def report_death(obj): 
...  # arrange for the death of OBJ to be announced 
...  def announce(wr): 
...   print 'gone' 
...  import weakref 
...  report_death.wr = weakref.ref(obj, announce) 
... 
>>> def make_dynamic_handler(): 
...  def handler(): 
...   pass 
...  # for debugging - we want to know when the handler is freed 
...  report_death(handler) 
...  return handler 
... 
>>> w = gtk.Window() 
>>> w.connect('realize', make_dynamic_handler()) 
10L 
>>> w.destroy() 
gone 

現在,如果你改變了代碼handler以包括循環引用,例如通過修改提自己:

def handler(): 
    handler  # closure with circular reference 

...摧毀通話將不再導致gone馬上打印 - 這將需要程序繼續工作,或者gc.collect()的顯式調用。在大多數Python和PyGTK程序中,自動釋放「正常工作」並且不需要努力去幫助它。

最終,只有可靠測試是否有內存泄漏運行可疑代碼在一個無限循環和監視過程的內存消耗 - 如果它的增長沒有界限的東西是沒有得到釋放,你有內存泄漏。

+0

非常感謝這個徹底的答案。我更關心拖放部分。由於涉及到一些用戶交互,無限循環不容易用於測試。 您的回答讓我現在信任PyGtk,因爲這些對象(函數,TargetList)應該由垃圾收集器管理。 謝謝。 – 2014-11-05 18:57:35

+0

@BastienJacquet沒問題 - 測試這種方法的另一種方法是將大對象附加到該函數,或者使用答案中顯示的'report_death'函數來監視它。 – user4815162342 2014-11-05 20:29:58