2012-09-21 15 views
5

私は、特定のpythonスクリプトのメモリ使用量について完全に混乱しています。私は実際にはいくつかの質問advice/Answersからadviceにもかかわらず、使用法をプロファイルする方法を知っていないと思います。Pythonでのメモリ使用量:memory_profilerとguppyの違いは何ですか?

私の質問はmemory_profilerguppy.hpyの違いは何ですか?なぜ私は大量のメモリを使用していると言っているのですが、もう1つは私にはないと言っているのですか?

私はpysamというバイオインフォマティクスのSAM/BAMファイルにアクセスするためのライブラリを使用しています。私の主なスクリプトは、SAM(ASCII)からBAM(Binary)に変換してその間のファイルを操作するときに、すぐにメモリ不足になります。

私は、各ステップでどれだけのメモリが割り当てられるかを理解するための小さなテストの例を作成しました。次に@profileデコレータをコメントアウトとguppy関連する行のコメントを解除

Filename: test_pysam.py 

Line # Mem usage Increment Line Contents 
================================================ 
    10        @profile # for memory_profiler 
    11        def samopen(filename): 
    12  10.48 MB  0.00 MB # print H.setrelheap() 
    13 539.51 MB 529.03 MB  samf = pysam.Samfile(filename) 
    14        # print H.heap() 
    15 539.51 MB  0.00 MB  pass 

、私は次の出力(python test_pysam.py)を得る:以下の出力でmemory_profiler(python -m memory_profiler test_pysam.py)結果とメモリ使用量を監視

# test_pysam.py: 

import pysam 
#from guppy import hpy 

TESTFILENAME = ('/projectnb/scv/yannpaul/MAR_CEJ082/' + 
       'test.sam') 
#H = hpy() 

@profile # for memory_profiler 
def samopen(filename): 
# H.setrelheap() 
    samf = pysam.Samfile(filename) 
# print H.heap() 
    pass 


if __name__ == "__main__": 
    samopen(TESTFILENAME) 

Partition of a set of 3 objects. Total size = 624 bytes. 
Index Count %  Size % Cumulative % Kind (class/dict of class) 
    0  1 33  448 72  448 72 types.FrameType 
    1  1 33  88 14  536 86 __builtin__.weakref 
    2  1 33  88 14  624 100 csamtools.Samfile 

1つのケースでは、ライン13の合計サイズは529.03 MBですもう一方は624バイトです。実際にここで何が起こっているのですか? 'test.sam'は〜52MBのSAMファイル(やはりASCII形式)です。それはsamtoolsに関連するCライブラリのラッパーなので、pysamを深く掘り下げるのはちょっと難しいことです。実際にSamfileが何であるかにかかわらず、私はそれを作成するためにどれくらいのメモリが割り当てられているかを知ることができるはずです。私の大規模で複雑なPythonプログラムの各ステップのメモリ使用量を正確にプロファイルするためには、どのような手順をとるべきですか?

+0

「test.sam」は、はるかに長い名前だったので2行目にあります。一度変更すると、ファイル名を1行にすると行番号情報がオフになることがわかりました。 – Yann

答えて

7

memory_profilerとguppy.hpyの違いは何ですか?

ヒープの内部ビューとOSのプログラムの外観の違いを理解していますか? (例えば、Pythonインタプリタが1MBでfreeを呼び出すと、それはすぐに、あるいは多分、1MB相当のページをOSに返すことはありません)。そうするなら、答えはかなり簡単です:memory_profilerあなたのメモリ使用をOSに要求しています。グーフィーはヒープ構造から内部的に考え出しています。

それ以外にも、memory_profilerには、コードの各行の後にレポートを印刷する機能を自動的に装備していない機能が1つあります。それ以外の点でははるかに簡単で簡単ですが、柔軟性は低くなります。あなたがやりたいことが分かっていて、memory_profilerがそうしていないと思われるものがあれば、それはおそらくできません。グッピーと、おそらくそれができるので、ドキュメントとソースを調べてください。

なぜ私は大量のメモリを使用していると言っているのですが、もう1つは私にはないと言っていますか?

確信はありませんが、ここにはいくつかの推測があります。答えは2つ以上の組み合わせである可能性があります。

おそらく、samtoolsはmmapを使用して十分に小さなファイルを完全にメモリにマップします。これにより、ファイルのサイズによってページ使用量は増加しますが、ヒープ使用量はまったく増加しません。

おそらく、samtoolsまたはpysamは、すぐに解放される多くの一時的なオブジェクトを作成します。あなたは断片化をたくさんすることができます(各ページにPyObjectsをいくつか生きているだけです)、あるいはあなたのシステムのmallocは割り振っている方法のためにフリーリストにたくさんのノードを置くべきだと決めているかもしれません。 OSにまだ戻されていないか、またはOSのVMが返された再生ページを持っていない可能性があります。正確な理由はほとんどいつでも推測することが不可能です。最も簡単なことは、解放されたメモリが決して返されないと仮定することです。

大規模で複雑なPythonプログラムの各ステップのメモリ使用量を正確にプロファイルするために使用する手順は?

OSの観点からメモリ使用量について質問しているのであれば、memory_profilerは必要なものを正確に実行しています。 pysamの掘り出し方は難しいかもしれませんが、@profileデコレータでいくつかの関数をラップするのは簡単です。次に、どのC関数がメモリの原因であるのかを知ります。もっと深く掘り下げたい場合は、明らかにCレベルでプロファイリングする必要があります(samtoolsドキュメントやsamtoolsコミュニティに情報がない限り)。

+0

偉大な答えは、ありがとう。 – Yann

関連する問題