Programing

파이썬 메모리 누수

lottogame 2020. 6. 3. 08:01
반응형

파이썬 메모리 누수


충분히 오래 실행하면 시스템의 모든 메모리를 사용하는 장기 실행 스크립트가 있습니다.

스크립트에 대한 자세한 내용을 다루지 않고 두 가지 질문이 있습니다.

  1. 준수해야 할 "모범 사례"가 있습니까?
  2. 파이썬에서 메모리 누수를 디버깅하는 기술은 무엇입니까?

이 기사를 살펴보십시오 : 파이썬 메모리 누수 추적

또한 가비지 수집 모듈에는 실제로 디버그 플래그가 설정 될 수 있습니다. 상기 봐 set_debug기능. 또한 호출 후 생성 된 객체의 유형을 결정하기 위해 Gnibbler의이 코드를 살펴보십시오 .


이전에 언급 한 대부분의 옵션을 시도했지만이 작고 직관적 인 패키지가 가장 좋습니다 : pympler

가비지 수집되지 않은 객체를 추적하는 것은 매우 간단합니다.이 작은 예를 확인하십시오.

통해 패키지를 설치 pip install pympler

from pympler.tracker import SummaryTracker
tracker = SummaryTracker()

# ... some code you want to investigate ...

tracker.print_diff()

출력에는 추가 된 모든 개체와 소비 한 메모리가 표시됩니다.

샘플 출력 :

                                 types |   # objects |   total size
====================================== | =========== | ============
                                  list |        1095 |    160.78 KB
                                   str |        1093 |     66.33 KB
                                   int |         120 |      2.81 KB
                                  dict |           3 |       840 B
      frame (codename: create_summary) |           1 |       560 B
          frame (codename: print_diff) |           1 |       480 B

이 패키지는 더 많은 기능을 제공합니다. 확인 pympler의 문서는 , 특히 섹션은 메모리 누수를 확인 .


비슷한 문제를 해결하는 데 도움이되는 mem_top 도구를 추천하겠습니다
.

파이썬 프로그램에서 메모리 누수의 주요 용의자를 즉시 ​​보여줍니다.


Tracemalloc 모듈 은 Python 3.4부터 내장 모듈 로 통합되었으며 이전 버전의 Python에서도 타사 라이브러리 로 사용할 수 있습니다 (테스트하지는 않았습니다).

이 모듈은 가장 많은 메모리를 할당 한 정확한 파일과 라인을 출력 할 수 있습니다. IMHO,이 정보는 각 유형에 할당 된 인스턴스 수보다 무한히 가치가 있습니다 (99 %의 많은 튜플이되어 단서이지만 대부분의 경우 거의 도움이되지 않습니다).

pyrasite와 함께 tracemalloc 을 사용하는 것이 좋습니다 . 10 회 중 9 회 , 피라 사이트 쉘 에서 상위 10 개 스 니펫실행하면 10 분 내에 누출을 해결할 수있는 충분한 정보와 힌트가 제공됩니다. 그러나 누출 원인을 여전히 찾을 수 없다면이 스레드에서 언급 한 다른 도구와 함께 pyrasite-shell이 ​​힌트를 줄 것입니다. 또한 pyrasite가 제공하는 모든 추가 도우미 (예 : 메모리 뷰어)도 살펴 봐야합니다.


전역 또는 정적 데이터 (장기 데이터)를 특별히 살펴 봐야합니다.

이 데이터가 제한없이 커지면 Python에서도 문제가 발생할 수 있습니다.

가비지 수집기는 더 이상 참조되지 않는 데이터 만 수집 할 수 있습니다. 그러나 정적 데이터는 해제해야하는 데이터 요소를 연결할 수 있습니다.

또 다른 문제는 메모리주기 일 수 있지만 적어도 이론적으로 가비지 콜렉터는 수명이 긴 일부 데이터에 연결되지 않는 한주기를 찾아서 제거해야합니다.

어떤 종류의 장수 데이터가 특별히 귀찮은가? 모든 목록과 사전을 잘 살펴보십시오. 제한없이 커질 수 있습니다. 사전에서는 dicts에 액세스 할 때 문제가 발생하지 않을 수도 있습니다. 사전의 키 수가 눈에 띄지 않을 수 있습니다 ...


프로덕션 환경과 같이 장기 실행 프로세스의 메모리 누수를 감지하고 찾으려면 이제 stackimpact를 사용할 수 있습니다 . 아래에 tracemalloc을 사용합니다 . 이 게시물에 더 많은 정보가 있습니다.

여기에 이미지 설명을 입력하십시오


파이썬에서 메모리 누수에 대한 "모범 사례"에 대해 잘 모르지만, 파이썬은 가비지 수집기에서 자체 메모리를 지워야합니다. 그래서 주로 가비지 컬렉터가 선택하지 않기 때문에 짧은 순환 목록을 확인하는 것으로 시작합니다.


모범 사례에 이르기까지 재귀 함수를 주시하십시오. 필자의 경우 재귀 문제가 발생했습니다 (필요하지 않은 곳). 내가하고있는 일에 대한 간단한 예 :

def my_function():
    # lots of memory intensive operations
    # like operating on images or huge dictionaries and lists
    .....
    my_flag = True
    if my_flag:  # restart the function if a certain flag is true
        my_function()

def main():
    my_function()

이 재귀 방식으로 작동해도 가비지 수집이 트리거되지 않고 함수의 잔해가 제거되지 않으므로 메모리 사용을 통해 매번 증가하고 증가합니다.

내 해결책은 my_function ()에서 재귀 호출을 꺼내고 다시 호출 할 때 main () 핸들을 갖는 것입니다. 이런 식으로 함수가 자연스럽게 끝나고 자체적으로 정리됩니다.

def my_function():
    # lots of memory intensive operations
    # like operating on images or huge dictionaries and lists
    .....
    my_flag = True
    .....
    return my_flag

def main():
    result = my_function()
    if result:
        my_function()

이것은 결코 완전한 조언이 아닙니다. 그러나 미래의 메모리 누수 (루프)를 피할 생각으로 작성할 때 명심해야 할 첫 번째 사항은 콜백에 대한 참조를 허용하는 모든 것이 해당 콜백을 약한 참조로 저장해야한다는 것입니다.

참고 URL : https://stackoverflow.com/questions/1435415/python-memory-leaks

반응형