2012-01-10 67 views
3

This bug report指出截至2007年6月,Python解釋器不會在使用嵌入式Python解釋器調用C/C++應用程序中的Py_Finalize之後清理所有分配的內存。建議在應用程序終止時調用Py_Finalize一次。Python 3解釋器在嵌入時是否泄漏內存?

This bug report指出,從版本3.3到2011年3月,解釋器仍然泄漏內存。

有沒有人知道這個問題的現狀?我很擔心,因爲我有一個應用程序,在該應用程序中,每個運行實例都會多次調用解釋器,並且遇到內存泄漏。

我已經使用boost :: python來處理引用計數,並且清除了在運行之間運行Python程序所創建的所有引用的全局字典。我有一些單身人士課程 - 這可能是問題嗎?

這是一個容易處理的問題還是Python解釋器中的錯誤?

回答

4

你可以看到這個bug(第一個,從2007年)被nnorwitz關閉爲「wontfix」,他的帖子在bug報告中。

爲什麼您不止一次致電Py_Initialize/Py_Finalize? 爲什麼不這樣做(我有點混合爲方便C和 的Python):

/* startup */ 
Py_Initialize(); 

/* do whatever */ 
while (moreFiles()) { 
    PyRun_SimpleString("execfile('%s')" % nextFile()); 
    /* do whatever */ 
} 

/* shutdown */ 
Py_Finalize(); 

的問題是,誰寫的Python模塊大多數人不擔心,如果他們的模塊會發生什麼得到最終確定並重新初始化,並且在最終確定期間通常不關心清理。模塊作者知道,當進程退出時,所有的內存都會被釋放,除此之外,不用擔心。

所以它不是真的一個bug,它真的有一千個bug - 每個擴展模塊都有一個bug。對於影響少數用戶的錯誤而言,這是一項巨大的工作量,其中大部分用戶都有可行的解決方法。

你總是可以省略對Py_Finalize的呼叫,第二次呼叫Py_Initialize是無操作。這意味着當您第一次運行Python腳本時,您的應用程序將使用額外的內存使用量,並且在退出之前,額外的內存不會返回到操作系統。只要你每隔一段時間仍然運行Python腳本,我就不會將它分類爲泄漏。您的應用程序可能不是Valgrind清潔的,但它比篩子更好。

如果您需要卸載(純)Python模塊以避免內存泄漏,則可以這樣做。請從sys.modules刪除它們。的Py_Finalize

缺點:如果您多次執行Python腳本,它並沒有太大的意義來運行它們之間Py_Finalize。每次重新初始化時都必須重新加載所有模塊;我的Python在啓動時加載了28個模塊。

附加評論:該bug不僅限於Python。如果您嘗試卸載並重新加載庫,任何語言的大量庫代碼都會泄漏內存。許多庫調用C代碼,很多C程序員都假設他們的庫被加載一次,並在進程退出時卸載。

+0

謝謝,雖然沒有簡單的解決方案有點令人失望。至少這證實了我目前的做法。 – user1140116 2012-01-11 02:26:46

+0

你試圖完成什麼? (通常,*表示*可以解決。) – 2012-01-11 05:48:39

+0

我正在製作一個將重複執行python腳本的Python IDE。每次腳本執行時,程序消耗的內存都會增加。我在應用程序啓動時調用Py_Initialize,並且從不調用Py_Finalize(由boost :: python調用)。腳本包含PyOpenGL和PyQt等庫。特別是在使用QImage時永遠不會釋放內存的問題。 – user1140116 2012-01-14 15:43:29