[Programming] Garbage Collection (GC)

2023. 6. 5. 16:35·Programming
728x90
728x90

Garbage Collection 이란?

Garbage collection (GC)은 Programming에서 memory를 관리하는 기법 중의 하나임.

 

Dynamical Memory Allocation에서
더 이상 사용되지 않는 object 또는 data에 할당된 memory를 자동으로 회수하는
Process를 의미한다.

https://miintto.github.io/docs/python-gc

위의 그림은 variable 이 Python에선 객체를 가리키는 reference에 불과함을 위에서 보여줌.
아래는 어느 변수도 가리키지 않는 객체는 free(메모리 해제, GC)됨을 의미.


GC를 지원하지 않는 경우

 

GC를 지원하지않는 C, C++ 등의 프로그래밍 언어에서는

  • 일반적으로 programmer가 memory의 할당과 해제를 explicitly(명시적으로) 처리해야하며,
  • 이를 잘못 수행하여 발생하는 memory leakage는 100% programmer의 책임이었음.

 

Pointer와 함께 이 명시적인 memory 관리 는

  • Programmer에게 강력한 권한을 주면서
  • 동시에 미숙한 programmer들의 잘못된 처리로 인해
  • 프로그램의 성능 저하 또는 예기치 않는 다운이 자주 발생케 되는 원인이 됨.

이에 대한 해결책으로
Pointer를 대체하는 reference가,
명시적 동적메모리 관리에 대해선 GC가 제안됨.


GC 의 역사

GC는

LISP 프로그래밍 언어에서 처음으로 도입(1959, McCarthy)되었으며

Java에서 사용되면서

최신의 High-level Programming Language에서 일반적으로 지원하는 기능으로 받아들여지게 됨.

 

GC는

  • runtime 중 memory를 모니터링하여
  • 더이상 필요하지 않은 memory 영역을 자동으로 회수함으로서 programmer의 부담을 덜어줌.

Reference Counting and Generation

GC에서
더이상 필요치 않은 memory 영역을 찾기 위해
다양한 algorithm과 method들이 제안되었음.

 

대표적인 것으로는

  • Reference Counting과
  • Tracing,
  • Generation 등이 있음.

 

가장 기본적인 Reference counting은
해당 memory 영역을 참고하고 있는 reference의 숫자를 counting하여
해당 숫자가 0이 되면 해당 memory영역을 회수하는 방식임
(단, Circular referencing에서 메모리누수가 발생하는 단점이 있음.).

circular references에 대한 간단한 그림. 객체 A,B 모두 ref.count=1이며 reference counting으로는 이들의 메모리 회수가 불가능함.

 

Python에서는 sys.getrefcount를 통해 refence들의 숫자를 확인 가능함.

import sys


x = [1, 2, 3]

# Reference Counting
ref_count = sys.getrefcount(x) - 1 # getrefcount의 argument로 
                                   # 넘겨져서 ref. counting이 
                                   # 하나 더 증가하여 출력되어 -1을 처리.
print(ref_count)
  • IPython 등이 아닌 Python의 순수 iteractive shell 로 수행하길 권함 (캐싱등을 피하기 위해 shell 실행후 최초로 실행할 것).
더보기

CPython을 사용한다면 다음의 코드를 이용하여 ref.count를 구할 수 있음.

import ctypes

# cpython에서 ref_count가 가능한 함수.
def ref_count(addr):
  # ctypes 라이브러리를 사용하여 주어진 메모리 주소에 있는 객체의 참조 카운트를 가져옴
  # ctypes.c_long: C long 정수 타입
  # .from_address(addr): 주어진 메모리 주소에서 C long 객체를 생성
  # .value: C long 객체의 값을 Python 정수로 가져옴 (CPython에서 참조 카운트에 해당)
  tmp = ctypes.c_long.from_address(addr).value
  return tmp

 

해당 구현의 CPython 코드를 보려면 다음 URL을 참고 : cpython/Include/object.h

 

GitHub - python/cpython: The Python programming language

The Python programming language. Contribute to python/cpython development by creating an account on GitHub.

github.com

 

다음의 내용은 Generation에 대한 내용으로, 일반적인 경우에는 생략해도 됨.

 

앞서 애기한 Circular referencing을 해결하기 위해

Python의 GC는 3개의 generation (0,1,2)별로 reference들을 관리하며,
각 세대별로 정해진 threshold에 따라 해당 임계치를 넘은 generation에 대해 GC가 수행됨.

해당 GC에서 살아남은 객체는 보다 높은 숫자의 generation으로 이동됨: generation 2는 최종 보관소로 오래 살아남은 객체들이 모임.

  • 이 Garbage Collector는 gc 모듈을 통해 프로그래머가 상호작용할 수 있음:
    • gc 모듈을 통해 동작을 끌수도 있는데, 이 경우 circular reference로 인한 메모리 누수를 해결할 수 없으니 주의할 것.
  • 새로운 객체가 만들어질때 파이썬은 객체를 메모리와 0세대에 할당한다.
  • 만약 0세대에서 객체가 할당된 횟수가 threshold 0보다 크면 collect_generations()를 실행.
  • collect_generations() 메서드가 호출되면
    • 모든 세대(기본적으로 3개의 세대)를 검사하며 오름차순으로 검사.
    • 여기서 검사는 각 generatiopn에 객체가 할당된 횟수가 해당 generation의 threshold 보다 큰 지 여부임.
    • 해당 n 세대(generation n)에 객체가 할당된 횟수 (count)가 각 세대에 대응되는 threshold n보다 크면 collect(generation = n)가 호출됨.
      • collect의 호출은 지정된 generation에서 GC 를 실행시킴.
      • 살아남은 객체들은 다음 generation으로 승격됨(이동)
      • generation n 에서 GC(=수집)이 일어나면, 한 단계 위세대의 객체 할당횟수(count)가 1 증가함.
      • collect(generation = n)은 프로그래머가 직접 호출가능.
    • 주의할 점은, 각 세대에서 제거되지 않은 객체들이 숫자가 높은 세대로 이동(승격)된다는 점이고, generation 2에서 계속 머물게 됨. 
  • 위에서 애기했듯이 0세대에 대해 GC가 수행되면 1세대의 count가 1 증가함.
    • 즉, threshold 0가 700이고, threshold 1이 10이면, 1세대는 $700\times 10=7000$번만에 GC가 수행됨.

다음 코드는 각 genration별로 할당된 threshold의 수를 확인할 수 있음.

import gc

print(gc.get_threshold()) # threshold
print(gc.get_count()) # collection 횟수
gc.collect() # 명시적으로 GC 실행.

Trade-off

  • GC는 Memory를 monitor하는데 필요한 연산과 자원을 소비함: 이는 전체 시스템의 수행속도를 느리게 할 수 있음.
  • Programmer가 GC를 완벽하게 명시적으로 제어하지 못하기 때문에, 매우 중요한 작업을 수행해야하는 시점에 GC가 수행되어 문제가 발생할 수도 있음.
  • GC의 경우, 잘못된 memory 회수는 program이 죽는 문제를 발생시키기 때문에 가급적 memory 회수를 하지 않는 경향성이 있음. 때문에 능숙한 programmer가 명시적으로 관리하는 경우에 비해 보다 많은 memory를 사용하는 경향성을 가지게 됨.
  • 불필요한 reference등의 존재로 인해 debugging이 보다 어려워진다는 단점이 있음.

참고자료.

https://youtu.be/pyqa47b4Fys?si=j_8I2KanAxFzSA8u

 

Python에서의 GC를 아주 잘 설명한 글임(강추):https://miintto.github.io/docs/python-gc

 

[파이썬] 가비지 컬렉션 - miintto.log

흔히 managed 언어라고 불리는 C언어에서는 프로그램을 짤 때 일일이 메모리를 할당하고 해제하는 작업이 필요했습니다. 하지만 Java, Python 과 같은 unmanaged 언어는 메모리를 신경 쓰지 않아도 그 자

miintto.github.io

 

다음 URL들도 좋은 자료임.

  • https://www.codesansar.com/python-programming/reference-counting.htm
  • Margurt's Blog : 파이썬의 메모리 관리
728x90

'Programming' 카테고리의 다른 글

[Python] Comprehension (list, dict, set) and Generator Expression  (0) 2023.06.06
[Python] Assignment와 Shallow Copy, Deep Copy  (0) 2023.06.05
[Python] Interpreter and PVM (Python Virtual Machine)  (2) 2023.06.05
[Python] recursive call : Fibonacci Sequence (and dynamic programming)  (0) 2023.05.24
[ML] Levenshtein distance  (1) 2023.05.17
'Programming' 카테고리의 다른 글
  • [Python] Comprehension (list, dict, set) and Generator Expression
  • [Python] Assignment와 Shallow Copy, Deep Copy
  • [Python] Interpreter and PVM (Python Virtual Machine)
  • [Python] recursive call : Fibonacci Sequence (and dynamic programming)
dsaint31x
dsaint31x
    반응형
    250x250
  • dsaint31x
    Dsaint31's blog
    dsaint31x
  • 전체
    오늘
    어제
    • 분류 전체보기 (781)
      • Private Life (13)
      • Programming (205)
        • DIP (116)
        • ML (34)
      • Computer (119)
        • CE (53)
        • ETC (33)
        • CUDA (3)
        • Blog, Markdown, Latex (4)
        • Linux (9)
      • ... (366)
        • Signals and Systems (113)
        • Math (176)
        • Linear Algebra (33)
        • Physics (43)
        • 인성세미나 (1)
      • 정리필요. (61)
        • 의료기기의 이해 (6)
        • PET, MRI and so on. (7)
        • PET Study 2009 (1)
        • 방사선 장해방호 (5)
        • 방사선 생물학 (3)
        • 방사선 계측 (9)
        • 기타 방사능관련 (3)
        • 고시 (9)
        • 정리 (18)
      • RI (0)
      • 원자력,방사능 관련법 (2)
  • 블로그 메뉴

    • Math
    • Programming
    • SS
    • DIP
  • 링크

    • Convex Optimization For All
  • 공지사항

    • Test
    • PET Study 2009
    • 기타 방사능관련.
  • 인기 글

  • 태그

    SIGNAL
    Programming
    Optimization
    numpy
    opencv
    signal_and_system
    인허가제도
    math
    linear algebra
    Python
    Term
    function
    random
    signals_and_systems
    SS
    Probability
    ML
    cv2
    fourier transform
    Vector
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
dsaint31x
[Programming] Garbage Collection (GC)
상단으로

티스토리툴바