2013-04-18 3 views
2

나는 루프를 돌리는 파이썬 스크립트를 가지고있다. 이 루프 내에서 함수 DoDebugInfo이 루프 반복마다 한 번 호출됩니다. 이 함수는 기본적으로 matplotlib을 사용하여 일부 그림을 하드 디스크에 인쇄하고, KML 파일을 내보내고 다른 계산을 수행하며, 은 아무 것도 반환하지 않습니다..파이썬 루프가 빠르게 메모리 사용량을 늘린다.

저는 파이썬이 실행될 때마다 함수 DoDebugInfo이 더 많은 RAM을 먹는다는 문제가 있습니다. 나는 어떤 변수가 각 루프의 크기를 증가시키고 있다고 생각한다. 프로그램이 메모리 풋 프린트를 가지고 호출하기 전에

=== before: 71598.08 
=== after: 170237.952 
=== before: 170237.952 
=== after: 255696.896 
=== before: 255696.896 
=== after: 341409.792 

당신이 볼 수 있듯이, 이후 :

print '=== before: ' + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1000) 
DoDebugInfo(inputs) 
print '=== after: ' + str(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1000) 

출력은 다음과 같습니다

나는 호출 전후에 다음 줄을 추가 증가하는 호출이지만 다음 호출 이전까지 안정적으로 유지됩니다.

왜 이럴까요? DoDebugInfo(inputs)은 아무 것도 반환하지 않는 함수이므로 일부 변수가 메모리에 남아있을 수 있습니까? 함수의 끝에서 모든 변수를 지울 필요가 있습니까?

편집 : DoDebugInfo 수입이 기능 :

def plot_line(x,y,kind,lab_x,lab_y,filename): 
    fig = plt.figure(figsize=(11,6),dpi=300) 
    ax = fig.add_subplot(111) 
    ax.grid(True,which='both') 
    #print 'plotting' 
    if type(x[0]) is datetime.datetime: 
     #print 'datetime detected' 
     ax.plot_date(matplotlib.dates.date2num(x),y,kind) 
     ax.fmt_xdata = DateFormatter('%H') 
     ax.autoscale_view() 
     fig.autofmt_xdate() 
    else: 
     #print 'no datetime' 
     ax.plot(x,y,kind) 
    xlabel = ax.set_xlabel(lab_x) 
    ax.set_ylabel(lab_y) 
    fig.savefig(filename,bbox_extra_artists=[xlabel], bbox_inches='tight') 

def plot_hist(x,Nbins,lab_x,lab_y,filename): 
    fig = plt.figure(figsize=(11,6),dpi=300) 
    ax = fig.add_subplot(111) 
    ax.grid(True,which='both') 
    ax.hist(x,Nbins) 
    xlabel = ax.set_xlabel(lab_x) 
    ax.set_ylabel(lab_y) 
    fig.savefig(filename,bbox_extra_artists=[xlabel], bbox_inches='tight') 

및 플롯 디스크에 10 개 숫자 같은 것을 사용 : 나는 plot_line을 사용하는 라인을 주석 경우

plot_line(index,alt,'-','Drive Index','Altitude in m',output_dir + 'name.png') 

문제가되지 않습니다를 이 코드 라인에 누수가 있어야합니다.

감사합니다.

+1

DoDebugInfo 함수를 보여주세요. – eumiro

+2

아무 것도 반환하지 않는 함수는 전역 변수를 변경하거나 호출간에 정리되지 않는 가변 매개 변수를 사용할 수 있습니다. –

+0

@eumiro 누수를 줄였습니다. DoDebugInfo 내부에서 사용하고있는 함수를 살펴보십시오. 어딘가에 누수가 있습니다. 감사합니다 – otmezger

답변

4

문제는 생성되는 숫자가 너무 많고 닫히지 않는 것에 달려 있습니다. 어떻게 든 파이썬은 그것들을 모두 살아있게합니다.

나는 나의 음모의 각

plt.close() 

plot_lineplot_hist 기능 및 문제가 사라 라인을 추가했다.

+1

'with' 문에서 그 것을 감쌀 수 있을지 궁금하다. – BenDundee

+1

+1 자체 답은 매우 유용합니다. – msw

+0

@BenDundee http://docs.python.org/2/library/contextlib.html 컨텍스트 관리자를 쉽게 만들 수 있습니다 – msw

0

크기가 제한없이 커지나요? 아주 적은 프로그램이나 라이브러리가 더 이상 사용하지 않을 때에도 할당 한 시스템에 힙을 반환하지만 CPython (2.7.3)도 예외는 아닙니다. 일반적인 원인은 malloc이며 요청시 프로세스 메모리가 증가하고 free에 빈 공간이 반환되지만 시스템에서 요청한 공간은 할당 해제되지 않습니다. 이 샘플 코드는 의도적으로 메모리를 잡고 공정 사용이 경계와 유한 것을 보여줍니다

(내 컴퓨터)에 출력이 부분에서,
import resource 

def maxrss(start, end, step=1): 
    """allocate ever larger strings and show the process rss""" 
    for exp in range(start, end, step): 
     s = '0' * (2 ** exp) 
     print '%5i: %sk' % (exp, 
      resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1000) 
    # s goes out of scope here and is freed by Python but not returned 
    # to the system 

try: 
    maxrss(1, 40, 5) 
except MemoryError: 
    print 'MemoryError' 

maxrss(1, 30, 5) 

가 :

26: 72k 
31: 2167k 
MemoryError 
1: 2167k 
6: 2167k 
... 
26: 2170k 

인터프리터가 실패했음을 보여주는 시스템에서 2^36 바이트의 힙을 가져 오지만 나중에 요청을 채우기 위해 "손에 들고있는"메모리가 남아 있습니다. 스크립트의 마지막 라인에서 파이썬이 현재 사용하고 있지 않더라도 사용하기위한 메모리가 있음을 보여줍니다.

+0

실제로 맥이 작동하기 어렵고 UI가 거의 동결 될 때까지 메모리에서 계속 증가합니다. 나는 파이썬 앱을 죽였고 4GB의 RAM을 릴리스했다. 나는 그가 더 멀리 가게하면 어떻게 될지 모르겠다. – otmezger

관련 문제