2011-09-17 31 views
3

Python​​には既知のメモリリークがありますか?私は​​を使用して、以下のスニペットのようなコードを持つPythonスクリプトを作成しています。何らかの理由でメモリリークが発生しています。この例の "while True"は、関数を呼び出すことによって発生したリークをテストすることです。これは、Python 2.5.4とWindows上で実行されている:Python:構造体のCTypesメモリリーク

import ctypes 
def hi(): 
    class c1(ctypes.Structure): 
      _fields_=[('f1',ctypes.c_uint8)] 
    class c2(ctypes.Structure): 
      _fields_=[('g1',c1*2)] 

while True: 
    test=hi() 

リークがProcessExplorerを使用して試験することができる - それがループし続けると、Pythonは、より多くのメモリを占有し続けます。 2つのStructureサブクラスが必要です.1つのクラスには(*演算子を使用して)他のものの「倍数」がありますが、条件がそれより基本的かどうかはわかりません。ループにdel testが追加されても、それでもメモリがリークします。

何が原因で起こっている可能性がありますか?

編集:誰かがそれはまだガベージコレクションを持っていない可能性があります示唆したので、ここではガベージコレクトん編集されたバージョンがあるが、まだメモリリークが発生する表示されます。

import gc 
import ctypes 
def hi(): 
    class c1(ctypes.Structure): 
      _fields_=[('f1',ctypes.c_uint8)] 
    class c2(ctypes.Structure): 
      _fields_=[('g1',c1*2)] 

while True: 
    test=hi() 
    test2=gc.collect() 
+0

どのくらい漏れますか? 'c1'ごとに1バイトずつ作成されますか?あなたが知っているように、「hi()」への50,000回の呼び出しごとに印刷されたカウンタを持ってください。 – agf

+0

ProcessExplorerでは、「ワーキングセット」のメモリは毎秒約20〜30 KBずつ着実に増加し、たびに「プライベートバイト」がそれに追いつきます。約12分後、私は既に59 MBのメモリを超えていて、通訳で実行されている2番目のスニペットを数えています。どれくらいのメモリが使用されているかを示すコード内にカウンタを配置するにはどうすればよいですか?誰かがこれについて私を裏付けることはできますか? – user553702

+0

最も簡単な方法は、 'itertools import count'を先頭に追加し、' while True: 'を' count(): 'に変更し、' if not c%50000:print c'をループに追加することです。次に、 'print'sがあまりにも頻繁であるか、あまりにも稀で有用でない場合は、' 50000'を増減してください。 – agf

答えて

2

メモリリークではありません。つまり、それは単にガベージコレクタがまだ実行されていないことを意味します。ガベージコレクタが動作しても、何らかの種類のメモリプーリングが行われているということは間違いありません。

ProcessExplorerは、特にメモリ用のデバッグツールではありません。

+0

最初に "import gc"を追加し、ループ内で "test2 = gc.collect()"を追加しても、それが占めるメモリは増え続けます。 「メモリプーリング」とはどういう意味ですか?メモリがある時点で解放されるべきではないか? – user553702

+0

メモリプールとは、領域が空きメモリを保持する(Python内で)確保されていることを意味します。それは最適化技術です。メモリだけが使用されているように見えます。 –

1

スクリプト自体は漏れません。 gc.set_debug(gc.DEBUG_LEAK)を実行すると、作成された構造タイプが収集可能であり、gc.garbageはすべてのループ反復で空のままであるため、収集できないオブジェクトはありません。 Linuxシステムでtimeでスクリプトを実行しても、メモリ消費量は恒常的に増加しません。

関連する問題