오늘도 개발

Python의 GC(Garbage Collection) 본문

웹 프로그래밍/Python3

Python의 GC(Garbage Collection)

Sueeeeeee 2022. 10. 31. 20:10

1. 파이썬의 메모리 구조

파이썬은 stack 메모리와 heap 메모리를 갖는다.

파이썬의 모든 것(변수, 함수 등)은 오브젝트이다.

 

파이썬은 오브젝트를 heap 메모리에 저장하고,

heap 메모리에 대한 포인터를 stack 메모리에 저장한다.

(Cpython이 변수를 처리하는 방법)

2. 파이썬의 GC(Garbage Collection)

Garbage Collection은 자동으로 메모리를 관리해주는 기능이다. 

파이썬은 기본적으로 Reference counting으로 GC를 실행한다.

reference counting을 사용할 수 없는 경우에는 보조로 generational GC(세대기반 GC)를 실행한다.

Reference counting

파이썬의 모든 오브젝트는 Reference Count라는 속성을 갖는다.

import sys

a = 'hi'
sys.getrefcount(a)
# 2

파이썬은 reference count에 해당 오브젝트를 가리키는 포인터가 스택에 몇 개 있는지 기록한다. 

어떤 오브젝트의 reference count가 0이 되면 자동으로 메모리에서 해제된다.   

다음 예시를 보자.

a = 'Java'
id(a)
# 4434034224

a = 'Python'
id(a)
# 4433715696

 

1) 'JAVA'라는 문자열 오브젝트를 힙메모리의 4434034224번에 할당

2) 변수 a가 'JAVA' 객체를 바인딩(변수 a가 'JAVA'오브젝트의 주소를 가리킨다는 뜻)

3) 'Python'이라는 문자열 오브젝트를 힙메모리의 4433715696번에 할당

4) 변수 a가 'Python' 객체를 바인딩

5) 'JAVA' 오브젝트는 레퍼런스가 없음 => 가비지 컬렉터가 없애버림

 

2) generational garbage collection(세대 기반 가비지 컬렉션)

하지만 오브젝트가 서로를 참조하고 있어서(=순환참조) Reference Counting을 쓰면 메모리를 절대 해제할 수 없는 경우가 있다.

 

다음은 순환참조의 예시이다.

li 오브젝트는 자기 자신을 참조하고 있다.

'del li' 이후 li의 reference count는 1이지만 사실 접근할 수 없는 변수이므로 메모리에서 해제되어야 한다. 

li = []
li.append(li)
del li

위와 같은 경우의 li 오브젝트는 세대 기반 가비지 컬렉션이 일어나는 시점에 메모리에서 해제된다. 

 

가비지 컬렉터가 작동하는 방식

가비지 컬렉터는 generation(세대)와 threshold(임계값)으로 오브젝트를 관리한다.

세대는 0, 1, 2세대로 구분되는데, 0이 신세대, 2가 구세대이다.

한 객체는 한 세대에만 속할 수 있다.

 

각 세대에는 임계값이 정해져 있어서(수동으로 변경 가능), 각 임계값을 초과하면 Garbage Collection이 일어난다. 

한 번 GC를 실행한 이후, 살아남은 오브젝트는 다음 세대로 이동한다.

 

기본적으로 세대가 낮을 수록 더 자주 카비지 컬렉션이 진행되도록 설정되어 있다.

최근 생성된 오브젝트가 삭제될 확률이 더 크기 때문이다.

 

GC의 threshold은 수동으로 변경 가능하고, 비활성화 할 수도 있다.

 

세대 기반 가비지 컬렉션과 성능

GC 실행 시 프로그램이 완전히 중지된다.

GC를 자주 실행하면 : 프로그램이 자주 중지되는 문제 발생

GC를 자주 실행하지 않으면 : 메모리에 필요없는 변수가 많이 쌓여서 비효율적

 

GC의 장점

개발자가 수동으로 신경쓰지 않아도 알아서 메모리 관리를 해주기 때문에 편리하다.

 

GC의 단점

어떤 메모리를 버려야 하는지 판단하는 데 비용이 든다.

GC가 실행되는 시점, GC 실행 시간을 미리 알기 어렵다.

=> 순환 참조가 일어나지 않는다고 확신할 수 있으면 GC를 끄는 게 낫다(ex. 인스타그램).

 

 

참고

파이썬 언어의 메모리 관리