2

ひどく必要なメモリを解放するために削除する必要があるプログラムに大きなリストがあるため、gc を理解しようとしています。私が答えたい基本的な質問はhow can I find what is being tracked by gc and what has been freed?、私の問題を示すコードです

import gc
old=gc.get_objects()
a=1
new=gc.get_objects()
b=[e for e in new if e not in old]
print "Problem 1: len(new)-len(old)>1 :", len(new), len(old)
print "Problem 2: none of the element in b contain a or id(a): ", a in b, id(a) in b
print "Problem 3: The reference counts are insanely high, WHY?? "

私見、これはdocsで対処されていない奇妙な動作です。まず、単一の変数を割り当てると、gc に複数のエントリが作成されるのはなぜですか? そして、なぜそれらのどれも私が作った変数ではないのですか?? get_objects() で作成した変数のエントリはどこにありますか?

EDIT:martjinの最初の応答に応えて、私は以下をチェックしました

a="foo"
print a in gc.get_objects()

まだ行きません:( aがgcによって追跡されていることを確認するにはどうすればよいですか?

4

1 に答える 1

2

の結果gc.get_objects()自体は追跡されません。そうしないと、循環参照が作成されます。

>>> import gc
>>> print gc.get_objects.__doc__
get_objects() -> [...]

Return a list of objects tracked by the collector (excluding the list
returned).

a低整数のシングルトンの 1 つを参照しているため、リストには表示されません。intPython は、 -5 から 256 までの値に対して同じオブジェクトのセットを再利用します。そのa = 1ため、追跡される新しいオブジェクトは作成されません。また、他のプリミティブ型も表示されません。

CPython ガベージ コレクションは、コンテナーの型、つまり他の値を参照できる型を追跡するだけで済みます。これは、GC が行う必要があるのは循環参照を壊すことだけだからです。

Python スクリプトが開始されるまでに、すでにいくつかの自動コードが実行されていることに注意してください。site.pyたとえば、リスト、マッピングなどを含むPythonパスを設定します。次に、int上記のメモ化された値があり、CPythontuple()は再利用のためにオブジェクトもキャッシュします。その結果、起動時に、簡単に5k以上のオブジェクトがすでにコードの1行が始まる前に生きています。

于 2013-05-18T17:58:46.717 に答える