pythonメモリ漏洩の診断


pythonで実装され、長期にわたって実行されているバックグラウンド・サービス・プロセスでは、メモリが増加し続けると、メモリの漏洩が発生する可能性があります.
最近私のプロジェクトでは、メモリが増加し続けていることがわかりました.goolgeを見てみると、
Tracing Python memory leaksは、診断方法を説明し、例を示した.私のケースはこの文書とは少し異なります.次に、私のケースと結びつけて、メモリの漏洩を診断する方法について説明します.
一、メモリ漏れの原因
pythonのようなゴミ回収をサポートする言語では、どうしてメモリが漏れるのでしょうか.要約すると、以下の3つの原因があります.
1.使用したC言語で開発した下位モジュールにメモリリークが発生した.
2、コードにはグローバルなリスト、dictまたは他のコンテナが使用されており、これらのコンテナにオブジェクトを挿入し続け、使用後に削除回収を行うことを忘れている.
3、コードに「参照サイクル」があり、pythonゴミ処理メカニズムが回収できない
二、メモリ漏洩の診断構想
いずれの方法のメモリ漏洩にしても、最終的にはpythonオブジェクトが成長し続けている形式があります.したがって、まずこれらの異常なオブジェクトを見つけることです.
三、メモリ漏洩の診断手順
使用するツール:gcモジュールと
objgraphモジュール
objgraphはメモリの問題を診断するのに役立つツールです
1、サービスプログラムの循環論理で、一つの診断点を選択する
2、診断点に次の診断文を挿入する

import gc
import objgraph
###         
gc.collect()
###            50      
objgraph.show_most_common_types(limit=50)


3、統計をチェックして、異常なオブジェクトを見つけます.
診断文が追加されたサービスプログラムを実行し、画面に印刷された統計情報をログにリダイレクトします.
しばらく実行すると、ログを分析して、どのオブジェクトが成長しているかを見ることができます.
私のプログラムを例にとると、ログをlogに記録します.txtでは、しばらく実行するとtupleとlistタイプのオブジェクトが増加し続けていることがわかります.

# grep "^list " log.txt
# grep "^tuple " log.txt

成長し続けるオブジェクトが、自分で実装したclassのような非汎用的なタイプであれば、問題は位置決めしやすいです.例えば、
Tracing Python memory leaksに記載されているケース.
tupleやlistのような汎用タイプでは、対象が何なのか、漏れがどこで起きているのかを知るには、何とかしなければなりません.私は検査の方式を採用した.プログラムのモジュール化は悪くないので、モジュールを無効にするたびに、プログラムを再実行し、ログを再確認し、tupleとlistが成長しているかどうかを確認することができます.これにより、障害を特定のモジュールに迅速に位置決めできます.
最後にやっと原因を見つけました.上にまとめた2つ目の原因です.
私のプログラムはマルチスレッドプログラムで、複数のスレッドが生産者として、1つのスレッドが消費者として、1つのtupleオブジェクトを非同期キューに送ることで通信します.消費者の処理速度が生産者の速度に追いつかず、同期も行われていないため、非同期キュー内のオブジェクトが増えている.
四、参考文書
1.
http://www.lshift.net/blog/2008/11/14/tracing-python-memory-leaks
2.
http://mg.pov.lt/blog/python-object-graphs.html
3.
http://mg.pov.lt/blog/hunting-python-memleaks