バグ(最初のものは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プログラマは、ライブラリが一度読み込まれ、プロセスが終了するとアンロードされると想定しています。
ありがとうございますが、単純な解決策がないことは少し残念です。少なくともこれは私の現在のアプローチを検証します。 – user1140116
達成しようとしていることは何ですか? (しばしば*解決することができます) –
私はPythonスクリプトを繰り返し実行するPython IDEを作っています。スクリプトが実行されるたびに、プログラムによって消費されるメモリが増加します。私はアプリケーションの起動時にPy_Initializeを呼び出し、Py_Finalizeを(決してboost :: pythonのように)呼び出さない。スクリプトには、PyOpenGLとPyQtを含むライブラリが含まれています。 QImageを使用しているときにメモリが割り当て解除されないという問題が特に発生しました。 – user1140116