2011-05-31 37 views
4

基本上,我有一個很長的運行過程,我希望能夠通過gc卸載模塊並恢復內存。我讀過關於刪除模塊How do I unload (reload) a Python module?,它似乎仍然存在懸掛gc引用。如果我將它導入到名稱空間中,我可以可靠地取消導入Python模塊嗎?

但是,如果我只在名稱空間內導入和使用模塊,該怎麼辦。換句話說,這樣的事情:

ns = {} 
exec somecode in ns 

然後,我會清理命名空間內的sys.modules,並通過刪除命名空間本身來完成。

會釋放內存在CPython中重用嗎?

如果沒有,那麼是有可能訪問使用ctypes的Python的C API的某些部分,做到這一點?

最終結果的重要的部分是,存儲器被釋放以使得在運行過程中幾個星期或幾個月,能夠可靠地unimport一個模塊沒有重新加載它。當然,在這段時間內,任何給定的模塊都可以被加載和卸載很多次。我假設一個模塊可以在加載時創建大量對象,並且正常清理(sys.modules和del)會將這些對象永遠留在內存中。

約亨:是的,我可以解決這個在許多方面,但我有興趣探索的Python的限制。

+2

你肯定你無法通過移動相關的功能整合到一個獨立的功能運行與解決此[多](http://docs.python.org/library/multiprocessing.html)或[子] (http://docs.python.org/library/subprocess.html)? – 2011-05-31 01:33:06

+3

聽起來像很多工作來節省幾個字節。您是否導入了數千個模塊,或者爲什麼您認爲卸載它們會值得? – 2011-05-31 01:34:57

回答

3

要取消導入模塊,您需要確保已刪除對模塊的所有引用。這意味着您必須刪除導入它的所有模塊中的引用,從sys.modules刪除引用,刪除對該模塊中定義的任何函數或類的引用,並刪除對模塊中定義的類的實例的對象的所有引用。

在幾乎所有情況下,這比檢索相對較少量的內存是值得的。如果你真的想試試這個,那麼gc.get_referrers()可能是有用的,因爲你可以刪除除了一個已知引用之外的所有模塊,然後追溯到找到還有其他引用它的地方。

3

如果你真正想要避免內存泄漏,你最好的辦法是安排一次導入模塊一次,正常情況下,sys.modules處於通常狀態。無論稍後導入模塊多少次,它都不會佔用更多的內存,因爲導入機器只會返回相同的模塊。

如果由於某種原因,這仍然不適合,說模塊正在動態創建,只需要使用一次,execcertainly isn't the solution。你應該考慮使用另一種執行模式,也許是爲了新的流程。

相關問題