본문 바로가기
Python

Python의 메모리 관리

by bryan.oh 2024. 8. 6.
반응형

준비물

Python을 사용하다 보면 자연스럽게 메모리 관리에 대해 고민하게 됩니다.
오늘은 Python의 메모리 관리 기법에 대해 알아보겠습니다.

1. Python 환경 설정

먼저 Python을 설치해야 합니다. 대부분의 OS에서는 기본적으로 Python이 설치되어 있지만, 최신 버전을 사용하고 싶다면 Python 공식 웹사이트에서 다운로드할 수 있습니다.

2. Python의 기본 메모리 관리 - 참조 카운팅

Python의 메모리 관리의 기본은 참조 카운팅입니다.

이게 뭐냐면, 객체가 몇 개의 참조를 받고 있는지를 세어주는 카운터입니다.

참조 카운트가 0이 되면, Python은 그 객체를 메모리에서 해제해 버립니다.

예제 코드:

import sys

# 객체 생성
obj = []
print("참조 카운트:", sys.getrefcount(obj))  # 참조 카운트: 2 (기본 1 + getrefcount 호출)

# 참조 추가
another_ref = obj
print("참조 카운트:", sys.getrefcount(obj))  # 참조 카운트: 3

# 참조 제거
del another_ref
print("참조 카운트:", sys.getrefcount(obj))  # 참조 카운트: 2

# 모든 참조 제거
del obj
# 객체는 이제 메모리에서 해제됩니다.

설명:

  • sys.getrefcount(obj)를 사용하면 참조 카운트를 확인할 수 있습니다.
  • 참조가 증가하면 카운트가 올라가고, 참조가 제거되면 내려갑니다.
  • 카운트가 0이 되면 메모리에서 해제됩니다. 자동으로!

3. 순환 참조 문제와 가비지 컬렉션

그런데 문제가 있습니다.

참조 카운팅만으로는 순환 참조를 해결할 수 없다는 거죠.

그래서 Python은 가비지 컬렉션을 사용합니다. 가비지 컬렉터는 메모리를 주기적으로 청소하며, 순환 참조를 감지하고 해결합니다.

순환 참조 예제:

import gc

class Node:
    def __init__(self, name):
        self.name = name
        self.reference = None

# 순환 참조 생성
node1 = Node("Node 1")
node2 = Node("Node 2")

node1.reference = node2
node2.reference = node1
# 이게 순환 참조 입니다. 

# 참조 제거
del node1
del node2

# 가비지 컬렉션 강제 실행
gc.collect()

print("가비지 컬렉션 완료!")

설명:

  • 순환 참조란 서로 다른 객체가 서로를 참조하는 상황을 말합니다.
  • gc.collect()를 사용하면 강제로 가비지 컬렉션을 실행할 수 있습니다.
  • Python은 주기적으로 가비지 컬렉션을 수행하여 메모리 누수를 방지합니다.

4. 가비지 컬렉션 최적화

Python의 gc 모듈을 이용하여 가비지 컬렉션의 동작을 최적화할 수 있습니다.

예를 들어, 가비지 컬렉션의 임계값을 조정하여 성능을 최적화할 수 있습니다.

임계값 설정 예제:

import gc

# 현재 임계값 확인
thresholds = gc.get_threshold()
print("현재 가비지 컬렉션 임계값:", thresholds)

# 임계값 조정
gc.set_threshold(700, 10, 10)

# 새로운 임계값 확인
new_thresholds = gc.get_threshold()
print("새로운 가비지 컬렉션 임계값:", new_thresholds)

설명:

  • gc.get_threshold()를 사용하면 현재 가비지 컬렉션의 임계값을 확인할 수 있습니다.
  • gc.set_threshold()를 통해 임계값을 조정하여 메모리 관리를 최적화할 수 있습니다.

5. 메모리 누수 방지

Python은 참조 카운팅과 가비지 컬렉션을 통해 메모리 누수를 최소화합니다.

하지만 여전히 개발자는 신경을 써야 합니다.

다음은 메모리 누수를 방지하기 위한 몇 가지 팁입니다:

  1. 순환 참조 피하기: 가능하면 순환 참조를 피하세요. 객체 간의 강한 결합을 약한 참조(weakref)로 대체할 수 있습니다.
  2. 리소스 해제: 파일, 네트워크 연결 등 외부 리소스를 사용 후에는 반드시 해제해야 합니다.
  3. 디버깅 도구 사용: 메모리 프로파일러 및 디버깅 도구를 사용하여 메모리 사용을 모니터링하고 최적화합니다.

마무리

Python의 메모리 관리 기법은 참조 카운팅과 가비지 컬렉션의 조합으로 이루어져 있습니다.
이러한 시스템은 강력하고 유연하여 다양한 애플리케이션에 적합한 성능을 제공합니다.
개발자는 이러한 기법을 이해하고 최적화하여 안정적이고 효율적인 코드를 작성할 수 있습니다.

728x90
반응형

댓글