python 프로그램 메모리 누 출 디 버 깅 기록

문제 설명
python 프로그램 을 디 버 깅 할 때 아래 코드 를 사용 하면 프로 세 스 가 시스템 메모리 값 을 차지 하 는 것 을 얻 을 수 있 습 니 다.프로그램 이 일정 시간 달 린 후에 프로 세 스 가 메모리 에 대한 점용 상황 을 그 릴 수 있다.

def memory_usage_psutil():
 # return the memory usage in MB
 import psutil,os
 process = psutil.Process(os.getpid())
 mem = process.memory_info()[0] / float(2 ** 20)
 return mem
프로 세 스 의 메모리 사용량 이 계속 증가 하 는 것 을 발 견 했 습 니 다.이것 은 논리 적 으로 정상 적 이지 않 아서 프로그램 이 Memory Leak 가 발생 했 을 수도 있다 고 생각 했 습 니 다.
python 프로그램의 Mem Leak
python 프로그램 은 C/C++처럼 malloc 메모리 에 free 와 같은 Memory Leak 가 없 을 수 없습니다.그러나'논리 적 으로 free 가 없다'는 경우 도 있 습 니 다.다음 코드 와 같 습 니 다.

def foo(a=[]):
 a.append(time.time())
 return a
매개 변수 a 와 같은 교체 가능 한 대상 은 조금 만 주의 하지 않 으 면 빠르게 증가 할 수 있다.솔직히 python 의 Memory Leak 는"프로 세 스 가 사용 하 는 메모리 가 영문 도 모 르 고 계속 올 라 갑 니 다"입 니 다.프로 세 스 가 메모리 사용량 을 계속 높 여 논리 적 예상 과 일치 하지 않 으 면 Memory Leak 가 발생 할 수 있 습 니 다.
다음 프로그램 을 예 로 들 어 Memory Leak 디 버 깅 과정 을 설명 합 니 다.

def memory_usage_psutil():
 # return the memory usage in MB
 import psutil,os
 process = psutil.Process(os.getpid())
 mem = process.memory_info()[0] / float(2 ** 20)
 return mem

def get_current_obj(a=[]):
 a.append([0]*1000)
 return a

def main(): 
 obj = []
 for i in range(10000):
 obj = get_current_obj(obj)
 if(i%100==0):
  print(memory_usage_psutil())

if __name__=='__main__':
 main()
디 버 깅 프로 세 스
프로 세 스 가 사용 하 는 메모리 크기 를 pmap-x[pid]로 봅 니 다.
우선 위 에 쓰 이 는 memory 가 아 닐 까 생각 했 어 요.usage_psutil 함수 통계 오류 네요.
프로그램 을 먼저 실행 하고 pmap 로 보 니 프로 세 스 메모리 사용량 이 확실히 높 습 니 다.이 명령 을 여러 번 실행 하면 메모리 가 계속 올 라 가 는 것 을 발견 할 수 있다.

GC 강제 실행(gc.collect())
GC 를 실행 해 야 하 는 곳 에 gc.collect()를 추가 합 니 다.

def main(): 
 obj = []
 for i in range(10000):
 obj = get_current_obj(obj)
 import gc;gc.collect()
 if(i%100==0):
  print(memory_usage_psutil())
GC 를 강제 한 후 프로그램 실행 이 느 려 졌 지만 메모리 가 계속 높 아 지 는 것 을 볼 수 있다.
memory 사용프로필 러 보기
메모리 설치profiler

pip install -U memory_profiler
@profile 로 수식 하려 면 메모리 의 함 수 를 봐 야 합 니 다.

@profile
def main(): 
 obj = []
 for i in range(10000):
 obj = get_current_obj(obj)
 if(i%100==0):
  print(memory_usage_psutil())
다음 명령 으로 프로그램 을 실행 합 니 다.

python -m memory_profiler main.py
프로그램 이 실 행 된 후 출력 결 과 는 다음 과 같 습 니 다.

Line # Mem usage Increment Line Contents
================================================
 12 28.570 MiB 0.000 MiB @profile
 13    def main():
 14 28.570 MiB 0.000 MiB obj = []
 15 106.203 MiB 77.633 MiB for i in range(10000):
 16 106.203 MiB 0.000 MiB  obj = get_current_obj(obj)
 17 106.203 MiB 0.000 MiB  if(i%100==0):
 18 105.445 MiB -0.758 MiB  print(memory_usage_psutil())
이렇게 하면 메모리 가 가장 빨리 오 르 는 몇 줄 의 코드 를 볼 수 있다.
python 대상 이 사용 하 는 메모리 크기 를 guppy 로 봅 니 다.
main 을 다음 과 같이 수정 하면 python 의 메모리 사용량 을 볼 수 있 습 니 다.

def main(): 
 obj = []
 for i in range(10000):
 obj = get_current_obj(obj)
 if(i%100==0):
  print(memory_usage_psutil())
  from guppy import hpy;hxx = hpy();heap = hxx.heap()
  print(heap)
다음은 출력 결과 입 니 다.python 프로그램 에서 각 대상 이 메모리 의 점용 을 큰 것 에서 작은 것 으로 배열 합 니 다.

 Index Count % Size % Cumulative % Kind (class / dict of class)
 0 10124 22 81944416 95 81944416 95 list
 1 16056 34 1325464 2 83269880 96 str
 2 9147 20 745616 1 84015496 97 tuple
 3 102 0 366480 0 84381976 98 dict of module
 4 287 1 313448 0 84695424 98 dict of type
 5 2426 5 310528 0 85005952 98 types.CodeType
 6 2364 5 283680 0 85289632 99 function
 7 287 1 256960 0 85546592 99 type
 8 169 0 192088 0 85738680 99 dict (no owner)
 9 123 0 142728 0 85881408 99 dict of class
결과 에서 볼 수 있 듯 이 95%의 프로 세 스 메모리 가 하나의 list 에 의 해 점용 되 었 다.
메모리 에서 가장 큰 list 의 데이터 형식 을 아래 와 같이 볼 수 있 습 니 다.

from guppy import hpy;hxx = hpy();byrcs = hxx.heap().byrcs; byrcs[0].byid
guppy 에 대한 상세 한 용법 은 여기(http://smira.ru/wp-content/uploads/2011/08/heapy.html)를 볼 수 있 습 니 다.
이상 python 프로그램의 메모리 누 출 디 버 깅 에 대한 기록 은 바로 편집장 이 여러분 에 게 공유 한 모든 내용 입 니 다.여러분 께 참고 가 되 고 저희 도 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기