본문 바로가기

개발 공부/FastAPI

[Python] Memory Leak 이해

Python Memory Leak 이해

Checkbox
 
Date

요약

  • Python은 몇 가지 알고리즘을 통해 GC를 돌리고, 메모리를 회수한다.
  • Tracemalloc을 통한 Core Dump 프로파일링
    • Python 오브젝트가 어디서 메모리 할당이 되었는 지 알 수 있다
    • 각 파일 이름과 라인 번호에 따라 메모리 블록 할당의 통계를 알 수 있다.
    • 메모리릭을 확인하기 위해 스냅샷 끼리 비교를 할 수 있다.
  • Tracemalloc 구조
    • python memory operations api를 오버라이드 했고, 해당 콜을 트레이스 할 수 있게 만든 라이브러리

내용

  • 파이썬 메모리 관리 방법 (Cpython-2016 자료 기준)
    • 파이썬 오브젝트는 메모리에 NAME → Reference → 오브젝트 형태로 메모리에 저장된다.
      null
    • name은 오브젝트의 라벨에 불과 하다
    • Object 의 여러 타입들
      • Simple Object(불변) - number, string (메모리에 단일 적재)
      • Container Object(가변) - dict, list, class (단순한 오브젝트를 포함한 적재)
    • Reference란?
      • 다른 오브젝트를 가리키는 name 또는 container object
    • Reference Count
      • 레퍼런스에서 가지고 있는 오브젝트 갯수
      • del 을 통해 레퍼런스를 지울 수 있지만, 오브젝트를 지우는 것은 아님
        x = 300 # 불변 300 이라는 값을 x가 가리킴 (call by value), Ref count 1
        y = 300 # 불변 300 이라는 값을 y가 가리킴 (call by value), Ref count 2
        z = [300, 300] # z 배열 안에 300은 300 값을 가리킴 (call by value), Ref count 4
        del x # Ref count 3 300이라는 값은 살아있음 
        
        y = None #Ref count 2 300이라는 값은 살아있음
        z = None #Ref count 0 300이라는 값을 가리키는 ref가 없기 때문에 
        				 #300값이 할당된 메모리 회수 
    • local vs global namespace
      • global 변수는 refcount가 0이 될 일이 없기 때문에 오브젝트가 삭제가 될 일이 없음
    • Python Garbage Collection 방법 (모두 사용)
      • Reference Count 방식
        • Ref Count가 0이 되면, 해당 오브젝트를 지우고 그 오브젝트와 관련된 다른 오브젝트들이 연쇄적으로 메모리 회수가 된다.
        • 순회적으로 서로 참조하는 Ref가 발생 시 GC는 오브젝트 메모리를 회수 할 수 없는 단점이 있음
      • Tracing 방식
        • GC root에 연결되어 있는 object와 reference 그래프를 마킹하고, 연결되지 않은 object와 reference를 삭제함
      • Generational
        • 대부분의 오브젝트가 오래 사용되지 않고 금방 죽는다.
        • 0,1,2 세대를 만들고 새롭게 생성된 오브젝트는 0세대를 할당 받는다.
        • 특정 세대가 임계치를 넘어 gc가 돌게 되면, 해당 세대보다 낮은 번호를 가지고 있는 세대도 gc가 돌게 된다.
          • 해당 임계치는 호스트 파일의
        • refcount가 0이상인 container object만 generation list에 저장된다.
        • Ref count, trace 방식을 통해 살아남은 오브젝트는 다음 세대 번호를 할당 받는다.
    • Global interpreter lock (GIL)
      • 인터프리터 내에서 동시에 오직 1개의 쓰레드만 동작이 된다.
      • 장점은 GC 구현이 간편해지지만, 1개의 쓰레드만 동작한다.
      • 따라서 멀티 코어인 CPU에서 이득을 얻기 위해서는 멀티 쓰레딩보다 멀티 프로세싱을 해야 한다.
      • 각 자의 프로세스는 GIL을 가지고, 프로세스 간 정보를 공유한다.
  • 메모리 누수를 잡기 위한 시나리오
    • Warm up
      • 1~2개 정도의 리퀘스트를 보내 API 웜업을 수행한다 (캐시되거나 등등을 수행)
    • Snapshot 생성 (AS-IS)
    • 트래픽 넣기
    • Snapshot 생성 (TO-BE)
    • 비교 및 분석

 

배울 점

  • Python 에서 메모리 관리를 어떻게 하는 지 알 수 있었다.
  • 처음에 warm-up을 하는 동작이 필요하다는 것과 tracemalloc이라는 모듈에 대해서 알 수 있었다.
  • GC가 도는 타이밍 공부 필요 (return 전에 gc가 도는 듯?)
  • GIL에 대한 이해
  • 실제 테스트 케이스 만들어서 돌려보기

 

추후 공부 해야할 것

  • ab 명령어
  • Fast API 메모리 누수 확인

참고자료

Debug Memory Leak In Python Flask | Python Object Memory Allocation Internals
https://youtu.be/s9kAghWpzoE
Nina Zakharenko - Memory Management in Python - The Basics - PyCon 2016
https://youtu.be/F6u5rhUQ6dU
Diagnosing and Fixing Memory Leaks in Python
uses Python extensively throughout our cloud security SaaS product and in our support tools, due to its ease-of-use, python security, extensive package library, and powerful language tools. One thing we've learned from building complex software for the cloud is that a language is only as good as its debugging and profiling tools.
https://www.fugue.co/blog/diagnosing-and-fixing-memory-leaks-in-python.html
No objects ever released by the GC, potential memory leak? · Issue #4649 · tiangolo/fastapi
First Check I added a very descriptive title to this issue. I used the GitHub search to find a similar issue and didn't find it. I searched the FastAPI documentation, with the integrated search. I already searched in Google "How to X in ...
https://github.com/tiangolo/fastapi/issues/4649#issuecomment-1236115694

 

728x90
반응형

'개발 공부 > FastAPI' 카테고리의 다른 글

[FastAPI] FastAPI를 적용하며  (2) 2024.01.07
[Python] Python 리스트 사용법 정리  (0) 2022.03.07
파이썬 개인 공부 정리  (0) 2020.05.18