2011-09-17 3 views
3

파이썬 ctypes에 메모리 누수가 있습니까? 어떤 이유로 인해 메모리 누수가 발생하고있는 ctypes을 사용하여 아래 스 니펫과 같은 코드가있는 Python 스크립트를 작성하고 있습니다. 이 예제에서 "while True"은 함수를 호출하여 발생하는 누수를 테스트하는 것입니다. 파이썬 2.5.4와 윈도우에서 실행되는 :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를 사용하여 테스트 할 수 있습니다 - 그것은 반복 유지로, 파이썬은 더 많은 메모리를 차지 유지합니다. 클래스 중 하나가 다른 하나의 "배수"(* 연산자 사용)를 갖는 두 개의 구조 하위 클래스가 필요하지만, 조건이 기본 클래스보다 더 확실하지는 않습니다. 루프에 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에서 "Working Set"메모리는 매초 약 20-30KB 씩 꾸준히 증가하며, 때로는 "Private Bytes"가이를 캐치합니다. 약 12 분 후에 저는 이미 59 MB의 메모리를 넘었고 통역사에서 실행중인 두 번째 스 니펫을 계산했습니다. 얼마나 많은 메모리가 사용되는지 알려주는 코드 내에 카운터를 두는 방법은 무엇입니까? 다른 사람이 나에 대해이 사실을 뒷받침 할 수 있니? – 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

메모리 풀은 여유 메모리를 보유하고있는 영역 (파이썬 내)을 따로 지정한다는 의미입니다. 그것은 최적화 기법입니다. 메모리가 사용되는 것처럼 보입니다. –

1

그 자체로는 스크립트가 누출되지 않습니다. gc.set_debug(gc.DEBUG_LEAK)으로 실행하면 생성 된 구조 유형을 수집 할 수 있으며 모든 루프 반복에서 gc.garbage이 비어 있으므로 수집 할 수없는 객체가없는 것으로 나타납니다. Linux 시스템에서 time으로 스크립트를 실행해도 메모리 소비가 꾸준히 증가하지는 않습니다.