2017-10-03 16 views
0

私は自分のパッケージから実行しているコードをいくつか持っていて、プログラムはそれより多くのメモリ(60GB)を使用しています。どのようにこのメモリが使用されている場所を解決しようとするために、現在の名前空間にすべてのオブジェクトのサイズ(バイト単位)を印刷できますか?Python:現在の名前空間にあるすべてのオブジェクトのサイズを取得する方法は?

私は

from pympler import asizeof 

for objname in dir(): 
    print(asizeof.asizeof(thing)/1024) # print size in kb 

ような何かをしようとしました。しかし、それは単に名前空間内のオブジェクトの名前を含む文字列のサイズを出力として、それは動作しません。このメソッドを使用するために名前空間内のすべてのオブジェクトへの参照を取得する方法はありますか、またはメモリを使用しているものを理解するためのより良い方法がありますか?

+0

はい、 'dir()'は*だけを文字列として生成します。 'globals()'と 'locals()'を使って名前空間を辞書として取得し、名前ではなくオブジェクト自身にアクセスできるようにします。 –

答えて

3

dir()は、ローカルスコープに存在する名前のみを返します。関数の外に、locals()globals()と同じマッピングであることを

for obj in locals().values(): 
     print(asizeof.asizeof(obj)/1024) 

注:辞書としてローカルの範囲を取得するにはlocals() functionを使用してください。

asizeof()が辞書にある場合、あなたはそれをフィルタリングする:

for name, obj in locals().items(): 
    if name != 'asizeof': 
     print(asizeof.asizeof(obj)/1024) 

dir()引数なしではsorted(locals())(ローカル名前空間のキーのソートされたリスト)と機能的に同等です。

+0

これを実行すると再帰の問題が発生するようです。私は自分自身で実行asizeofのために想像して、地元の人々()によって作成された辞書からこれを削除する簡単な方法はありますか? – SomeRandomPhysicist

+0

@SomeRandomPhysicist: 'dict.items()'の名前と値のペアを反復してフィルタリングすることができます。代わりに 'if obj is asizeof:'を使用してください。 –

+0

私はasizeofを参照するいくつかの一時変数を持っていましたので、これらをフィルタリングするより一般的な方法は単にexcept except文でした。 – SomeRandomPhysicist

1

gc.get_objects()を使用すると、特定の名前空間内のオブジェクトだけでなく、コレクタによって追跡されたすべてのオブジェクトをフェッチすることができます。私はそれを使用して各タイプのインスタンスの数を数えることから始めます。それはそれがあなた自身の手がかりを与えるかもしれません。

from collections import Counter 
c = Counter(type(o) for o in gc.get_objects()) 
print(c.most_common(20)) 

次に、疑わしい疑いのある人物のサイズを調べることがあります。

+2

が真です。私はそれを更新しました。無限ループを避けるためにはまだ注意が必要ですが、 'get_objects()'は過去のメモリリークの出発点です。 – Duncan

関連する問題