36

Pythonでオブジェクトへのすべての参照を見つける良い方法は何ですか?

私が尋ねる理由は、「メモリ リーク」があるように見えるからです。Web ブラウザからサーバーに画像ファイルをアップロードしています。これを行うたびに、サーバーのメモリ使用量は、アップロードされたばかりのファイルのサイズに比例して増加します。このメモリは python ガベージ コレクションによって解放されることはありません。そのため、各リクエストの最後でも、削除されていない、またはスコープ外に出ていない画像データを指す参照がおそらくあると思います。

Python に「まだこのメモリを指している参照は何ですか?」と質問できると便利だと思います。何がガベージ コレクションの解放を妨げているのかを突き止めることができます。

現在、Heroku サーバーで Python と Django を実行しています。

4

2 に答える 2

80

Python のgcモジュールにはいくつかの便利な機能がありgc.get_referrers()ますが、探しているものはそのように思えます。次に例を示します。

import gc


def foo():
    a = [2, 4, 6]
    b = [1, 4, 7]

    l = [a, b]
    d = dict(a=a)
    return l, d

l, d = foo()
r1 = gc.get_referrers(l[0])
r2 = gc.get_referrers(l[1])

print r1
print r2

それを実行すると、次の出力が表示されます。

[[[2, 4, 6], [1, 4, 7]], {'a': [2, 4, 6]}]
[[[2, 4, 6], [1, 4, 7]]]

l最初の行はanddで、2 行目は just であることがわかりますl

私の簡単な実験では、結果が常にこのようにクリーンであるとは限らないことがわかりました。たとえば、インターンされた文字列とタプルには、予想よりも多くのリファラーがあります。

于 2015-10-28T18:12:01.337 に答える
10

Python の標準ライブラリにはgc、ガベージ コレクタ API を含むモジュールがあります。あなたが望む可能性のある機能の1つは

gc.get_objects()

この関数は、ガベージ コレクターによって現在追跡されているすべてのオブジェクトのリストを返します。次のステップはそれを分析することです。

追跡したいオブジェクトがわかっている場合は、sysモジュールのgetrefcount関数を使用できます。

>>> x = object()
>>> sys.getrefcount(x)
2
>>> y = x
>>> sys.getrefcount(x)
3
于 2012-08-09T21:02:28.850 に答える