Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python 객체 파괴와 가비지 컬렉션(Garbage Collection) 완벽 이해


Python은 더 이상 필요하지 않은 객체(내장 타입 또는 클래스 인스턴스)를 자동으로 삭제하여 메모리 공간을 확보합니다. 이처럼 Python이 주기적으로 사용되지 않는 메모리 블록을 회수하는 과정을 가비지 컬렉션(Garbage Collection)이라고 부릅니다.

Python의 가비지 컬렉터는 프로그램 실행 중에 동작하며, 객체의 참조 카운트(reference count)가 0에 도달하는 시점에 트리거됩니다. 객체를 가리키는 별칭(alias)의 수가 변하면 그에 따라 참조 카운트도 함께 변경됩니다.

객체에 새로운 이름이 할당되거나 컨테이너(리스트, 튜플, 딕셔너리)에 저장되면 참조 카운트가 증가합니다. 반대로 del 문으로 객체를 삭제하거나, 참조가 다른 객체로 재할당되거나, 참조가 유효 범위(scope)를 벗어나면 참조 카운트가 감소합니다. 참조 카운트가 0이 되면 Python이 해당 객체를 자동으로 회수합니다.

a = 40    # 객체 <40> 생성
b = a     # <40>의 참조 카운트 증가
c = [b]   # <40>의 참조 카운트 증가
del a     # <40>의 참조 카운트 감소
b = 100   # <40>의 참조 카운트 감소
c[0] = -1 # <40>의 참조 카운트 감소

일반적으로 가비지 컬렉터가 더 이상 참조되지 않는 고아(orphaned) 인스턴스를 파괴하고 메모리를 회수하는 시점은 눈치채기 어렵습니다. 하지만 클래스는 __del__()이라는 특수 메서드, 즉 소멸자(destructor)를 구현할 수 있으며, 이 메서드는 인스턴스가 소멸되기 직전에 호출됩니다. 소멸자는 인스턴스가 사용한 메모리 외부의 자원(파일 핸들, 네트워크 연결 등)을 정리하는 용도로 활용할 수 있습니다.

예제

다음 예제의 __del__() 소멸자는 곧 소멸될 인스턴스의 클래스 이름을 출력합니다.

#!/usr/bin/python
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __del__(self):
        class_name = self.__class__.__name__
        print(class_name, "destroyed")

pt1 = Point()
pt2 = pt1
pt3 = pt1
print(id(pt1), id(pt2), id(pt3))  # 객체들의 id 출력
del pt1
del pt2
del pt3

실행 결과

위 코드를 실행하면 다음과 같은 결과가 출력됩니다.

3083401324 3083401324 3083401324
Point destroyed

참고: 이상적인 코드 구조를 위해서는 클래스를 별도의 파일로 정의한 뒤, 메인 프로그램 파일에서 import 문을 사용하여 가져오는 방식을 권장합니다.