2011-07-01 5 views
7

長時間走っている大きなサーバーがあり、数週間にわたってメモリ使用量が着実に増加しています。Pythonでuncollectableなゴミを作成する方法は?

一般に、以下に指摘されているように、その漏れは私の問題です。しかし、私は多くのことをする必要はありませんので、私は漏れがあるかどうかを見たいと思っています。

コンソール出力の取得は難しいので、私はgc.set_debug()で動作していません。私は簡単にAPIを追加してgc.collect()を実行してから、gc.garbageを繰り返し実行し、その結果をHTTP経由で私に送り返すので、これは大きな問題ではありません。

私の問題は、短時間ローカルに実行すると、私のgc.garbageは常に空です。私はそれを展開する前にリークを列挙したコードをテストすることはできません。

ガーベッジの回収不可能なビットを作成するための簡単なレシピがありますので、ごみをリストするコードをテストできますか? (ガベージコレクタがでファイナライザを実行するためにどの順序を知らないため)

+0

答えはありませんが、Giovanni Bajoは先月EuroPythonでメモリリークをデバッグする素晴らしい話をしました。トークビデオはここにあります:http://ep2011.europython.eu/conference/talks/debugging-and-profiling-techniques – grifaton

+0

少なくとも1つの種が必要だと思われます:( – Will

答えて

12

ファイナライズオブジェクトの任意のサイクル(すなわち、__del__メソッドを持つオブジェクトである)回収不能である:

>>> class Finalizable: 
...  def __del__(self): pass 
... 
>>> a = Finalizable() 
>>> b = Finalizable() 
>>> a.x = b 
>>> b.x = a 
>>> del a 
>>> del b 
>>> import gc 
>>> gc.collect() 
4 
>>> gc.garbage 
[<__main__.Finalizable instance at 0x1004e0b48>, 
<__main__.Finalizable instance at 0x1004e73f8>] 

しかし、一般的な点としてファイナライザを使用する習慣がない限り、あなたの問題は回収不可能なゴミであると私には思われません。これは、ライブオブジェクトの蓄積やメモリの断片化(Pythonは移動しないコレクタを使用するため)の可能性が高くなります。

+0

すみませんが、私はちょうど見るためにゴミを作りようとしていますどのようにPythonで動作するのですか?上記の例では、ゴミは何ですか?それらの参照が削除される前のaとbのインスタンス?http://www.pythontutor.com/visualize.html#code=class+Finalizable%3A% 0A ++++ def + __ del __(自己)%3A +パス%0A%0Aa +%3D + Finalizable()%0Ab +%3D + Finalizable()%0Aa.x +%3D + b%0Ab.x +%3D + a% – BugShotGG

+2

あなた自身を参照してください:あなたがそれらを削除する前に 'id(a)'と 'id(b)'を表示して、if()を参照してください:ifA(id(a))%0Adel +%0Adel + b&mode = display&cumulative = true&py = 3&curInstr =これらのidはコレクションの後に 'id(gc.garbage [0])'と 'id(gc.garbage [1])'と一致します。 –

+0

うまくいった! – BugShotGG

関連する問題