質問: Python3.6 Winodows10 64bit Pythonで規模が大きいコードを書いています。 コードを実行すると消費するメモリの量が大きくメモリリークがみられました。 まず第一にtracemallocにより、メモリリークの原因と考えられるObjectを見つけ出しました。 しかし、どこでリークしているのかわかりませんでした。(広範囲に使用している為 gcの公式を読んでいると https://docs.python.jp/3/library/gc.html#gc.get_referrers https://docs.python.jp/3/library/gc.html#gc.get_referents このようなMethodを用いて参照しているObjectを取得できることがわかりました。(正しい? 次にこの参照元を調べようとしたのですが、出力されるリストに見覚えはありません。 このMethodに対する認識は正しいのでしょうか? また参照元のObjectのプログラムにおける場所や生成元を調べる方法は無いでしょうか?
回答: Pythonではないですが、3年前に別言語でメモリリークの調査をした時の手順を。 今ならもっといい手法がある気がしますが。。 1,対象のObject自身が自身が関数呼び出しでメモリリークをおこなさない事を保証する。 まずそのObject自体は外部リソース(file/network/database/thread)を使っていますか? 使っているならwith文や`contextlib.closing`を使った形にして確実に解放される形に変更してくださいな。 2,調査について オブジェクト生成時に以下の情報をインスタンス変数に保持しておき調査情報としておきました。 2-1,実行スタックフレーム tracebackモジュールが使える気がします。 2-2,生成時間(ミリ秒単位) ログファイルとの突合せ用。 2-3,コンストラクタ引数のパラメータをhash値化したもの。 3,経験則だと 3-1,コンテナやイベントリスナに追加したまま削除せずに放置でメモリリークになるパターンがあります。 => 弱参照weakrefを使うことも検討してみてくださいな。 3-2,単純にGCがまだ実行されていないだけという事もあるので、GC.Collect()しても徐々にメモリが増加する特微が出るか確認してくださいな。