web-dev-qa-db-ja.com

Pythonガベージコレクション

私はいくつかのpythonコードを作成してループ内でオブジェクトを作成し、反復ごとにこのオブジェクトを同じタイプの新しいオブジェクトで上書きします。これは10.000回行われ、Pythonは、私の3GBが使用されるまで毎秒7MBのメモリを消費しますRAM。メモリからオブジェクトを削除する方法を誰かが知っていますか?

39
utdiscant

十分な情報が提供されていません-これは、作成しているオブジェクトの詳細と、ループ内でそれを使用して他に何をしているのかによって異なります。オブジェクトが循環参照を作成しない場合は、次の反復で割り当てを解除する必要があります。たとえば、コード

for x in range(100000):
  obj = " " * 10000000

メモリ割り当てが増え続けることはありません。

20
Vinay Sajip

これは循環参照だと思います(ただし、この情報についての質問は明確ではありません)。

この問題を解決する1つの方法は、ガベージコレクションを手動で呼び出すことです。ガベージコレクターを手動で実行すると、循環参照オブジェクトもスイープされます。

import gc

for i in xrange(10000):
    j = myObj()
    processObj(j)
    #assuming count reference is not zero but still
    #object won't remain usable after the iteration

    if !(i%100):
        gc.collect()

ここでは独自のオーバーヘッドがあるため、ガベージコレクタをあまり頻繁に実行しないでください。すべてのループでガベージコレクターを実行すると、解釈が非常に遅くなります。

28
hasanatkazmi

これは、python 2.5の一部のタイプで修正された古いエラーです。何が起こっていたかというと、pythonは空のリストなどの収集にあまり適していませんでした/ dictionaries/tupes/floats/ints。python 2.5では、これはほとんど修正されました。ただし、floatとintは比較のためのシングルトンなので、これらの1つが作成されると、インタプリタは生きています。大量のフロートを処理するとき、ユニークであるという厄介な癖があるため、私はこの最悪の事態に悩まされました。これは特徴付けられました for python 2.4 =折りたたみについて更新 python 2.5

私が見つけた最良の方法は、python 2.5以降にアップグレードして、リスト/辞書/タプルの問題に対処することです。数値の場合、唯一の解決策は、数値はpythonに入ります。私はc ++オブジェクトへの独自のラッパーを使用してそれを実行しましたが、numpy.arrayが同様の結果をもたらすという印象を持っています。

ポストスクリプトとして、python 3でこれに何が起こったかはわかりませんが、数値がシングルトンの一部であることに疑いがあります。そのため、メモリリークは実際には言語。

13
Pete Peterson

循環参照を作成している場合、オブジェクトはすぐに割り当て解除されませんが、GCサイクルが実行されるまで待機する必要があります。

weakref モジュールを使用してこの問題に対処するか、使用後にオブジェクトを明示的に削除することができます。

7
Algorias

私の場合(Python 2.5.1)で、__del__()メソッドを持つクラスを含む循環参照があると、ガベージコレクションがタイムリーに発生しなかっただけでなく、 、スクリプトの終了時でも、オブジェクトの__del__()メソッドが呼び出されなかったため、循環参照を解除するために weakref を使用しましたが、すべて正常でした。

これをまとめるためにコメントにすべての情報を提供してくれたマイルスへの称賛。

3
Von

REPLで実行できる1つのことは、変数の逆参照を強制することです。

>>> x = 5
>>> x
5
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
1
Mark Rushakoff

weakrefは 説明された例 のように、循環オブジェクト構造化コードに使用できます

0
alkanschtein