2

最近objgraphドキュメントを読んで、次のコードについて混乱しました

>>> class MyBigFatObject(object):
...     pass
...
>>> def computate_something(_cache={}):
...     _cache[42] = dict(foo=MyBigFatObject(),
...                       bar=MyBigFatObject())
...     # a very explicit and easy-to-find "leak" but oh well
...     x = MyBigFatObject() # this one doesn't leak

「非常に明確で見つけやすい「リーク」」であることを示しています。これにはメモリリークがありますか?それはdict _cacheですか?

4

2 に答える 2

7

_cache変更可能なデフォルトを持つキーワード引数であり、実際には関数本体で変更されています。MyBigFatObjectsこれにより、その変更可能なキーワード引数にインスタンスが永続的に保存されます。

これはリークというよりは、変更可能なキーワード引数の寿命に関する誤解です。関数自体はdel _cache[42]、これらのオブジェクトを削除するために呼び出すことができます。

この件名の詳細については、「最小の驚き」と可変デフォルト引数を参照してください

于 2012-07-27T08:56:32.207 に答える
1

dict は変更可能であるため、それに加えられた変更は呼び出し元にも影響するため、2 への参照はMyBigFatObject保持されます。

明示的に削除する必要があります(del _cache[42])。辞書またはその他の可変オブジェクトの独自のコピーを変更する必要があります(そのためにコピーモジュールを使用できます)。

于 2012-07-27T08:59:19.737 に答える