バグ (最初のもの、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 つずつ、実に 1000 のバグです。少数のユーザーに影響を与えるバグの場合、これは膨大な量の作業であり、そのほとんどには実行可能な回避策があります。
への呼び出しはいつでも省略できます。2 回目のPy_Finalize
呼び出しPy_Initialize
は何もしません。これは、Python スクリプトを最初に実行するときにアプリケーションが追加のメモリを使用することを意味し、その追加のメモリは終了するまで OS に返されません。Python スクリプトを時々実行している限り、それをリークとは分類しません。あなたのアプリケーションは Valgrind クリーンではないかもしれませんが、ふるいのようにリークするよりはましです。
メモリ リークを避けるために (純粋な) Python モジュールをアンロードする必要がある場合は、それを行うことができます。から削除するだけsys.modules
です。
の欠点Py_Finalize
: Python スクリプトを繰り返し実行している場合、それらの間で実行することはあまり意味がありませんPy_Finalize
。再初期化するたびに、すべてのモジュールをリロードする必要があります。私のPythonは起動時に28個のモジュールをロードします。
追加の解説:バグは Python に限定されません。ライブラリをアンロードして再ロードしようとすると、どの言語でもかなりの量のライブラリ コードでメモリ リークが発生します。多くのライブラリが C コードを呼び出します。多くの C プログラマは、ライブラリが一度ロードされ、プロセスが終了するとアンロードされると想定しています。