2012-01-10 13 views
3

This bug reportは、2007年6月現在のPythonインタプリタは、Pythonインタプリタが組み込まれたC/C++アプリケーションでPy_Finalizeを呼び出した後、割り当てられたすべてのメモリをクリーンアップしないと述べています。アプリケーションの終了時にPy_Finalizeを1回呼び出すことをお勧めしました。埋め込み時にPython 3インタプリタがメモリをリークしますか?

This bug reportは、バージョン3.3以降および2011年3月現在、インタープリタがまだメモリをリークしていると述べています。

この問題の現在の状態を知っている人はいますか?インタプリタが実行中のインスタンスごとに複数回呼び出され、メモリリークが発生しているアプリケーションがあるため、心配しています。

私はすでにboost :: pythonを使用して参照カウントを処理していますが、実行の間にPythonプログラムを実行することによって作成されたすべての参照のグローバル辞書をクリアします。私はシングルトンクラスをいくつか持っています - これらは問題かもしれませんか?

これは扱いにくい問題か、それともPythonインタープリタのバグですか?

答えて

4

バグ(最初のものは2007年)がnnorwitzによって "wontfix"として閉じられていることがわかります。彼の投稿はバグレポートにあります。

なぜPy_Initialize/Py_Finalizeを複数回電話しますか? は、なぜこのような何かを(私はちょっと便宜上Cと のPythonを混合しています)しない:

/* startup */ 
Py_Initialize(); 

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

/* shutdown */ 
Py_Finalize(); 

問題は、Pythonモジュールを書くほとんどの人は彼らのモジュールとどうなるか心配していないということですファイナライズされ、再初期化され、ファイナライズ中にクリーンアップを気にしないことがよくあります。モジュールの作者は、プロセスが終了するとすべてのメモリが解放され、それ以上のことは気にしないことを知っています。

これは実際には1つのバグではなく、実際には1つの拡張モジュールごとに1つのバグです。少数のユーザーに影響を与えるバグのための膨大な作業であり、そのほとんどは実行可能な回避策があります。

Py_Finalizeへの呼び出しを省略することができます。Py_Initializeを呼び出すと、2度目はノーオペレーションです。つまり、Pythonスクリプトを最初に実行するときにアプリケーションで追加のメモリ使用量が使用され、終了するまで追加のメモリがOSに返されません。 Pythonスクリプトを毎回実行している限り、私はそれをリークとして分類しません。あなたのアプリケーションはValgrind-cleanではないかもしれませんが、ふるいのような漏れよりも優れています。

メモリーが漏れないように(純粋な)Pythonモジュールをアンロードする必要がある場合は、それを行うことができます。 sys.modulesから削除してください。 Py_Finalize

欠点:あなたが繰り返しPythonスクリプトを実行している場合は、それらの間Py_Finalizeを実行するために、あまり意味がありません。再初期化するたびにすべてのモジュールをリロードする必要があります。私のPythonは起動時に28個のモジュールを読み込みます。

追加のコメント:バグはPythonに限定されません。ライブラリをアンロードしてリロードしようとすると、どの言語のライブラリコードでも大量のメモリがリークします。多くのライブラリがCコードを呼び出します。多くのCプログラマは、ライブラリが一度読み込まれ、プロセスが終了するとアンロードされると想定しています。

+0

ありがとうございますが、単純な解決策がないことは少し残念です。少なくともこれは私の現在のアプローチを検証します。 – user1140116

+0

達成しようとしていることは何ですか? (しばしば*解決することができます) –

+0

私はPythonスクリプトを繰り返し実行するPython IDEを作っています。スクリプトが実行されるたびに、プログラムによって消費されるメモリが増加します。私はアプリケーションの起動時にPy_Initializeを呼び出し、Py_Finalizeを(決してboost :: pythonのように)呼び出さない。スクリプトには、PyOpenGLとPyQtを含むライブラリが含まれています。 QImageを使用しているときにメモリが割り当て解除されないという問題が特に発生しました。 – user1140116