# 파이썬의 실행 구조 및 메모리 모델 #
1. 📙 파이썬 인터프리터 구조
1-1📒 CPython, PyPy, Jython 차이
1-2📒 바이트코드와 인터프리터 동작
2. 📙 메모리 모델 및 객체 구조
2-1📒 변수 참조, 객체 ID, 가비지 컬렉션
2-2📒 참조 카운팅과 순환 참조 처리
.py 파일
↓ (컴파일)
바이트코드(.pyc)
↓ (인터프리터)
Python Virtual Machine(PVM)에서 실행
파이썬은 먼저 코드를 '바이트 코드'로 변환합니다.
이 바이트코드는 "PVM(Python Virtual Machine)"이 해석하여 실행합니다.
구현체 | 설명 | 특징 |
---|---|---|
CPython | 가장 널리 쓰이는 공식 구현체 | - C로 구현 - 바이트코드 → PVM에서 해석 실행 - 참조 카운팅 기반 메모리 관리 |
PyPy | 성능 최적화된 구현체 | - JIT 컴파일 사용 - 루프/함수 실행을 기계어로 변환해 캐싱 - 속도 ↑ (특히 반복 연산, 수치 계산) |
Jython | Java 기반 파이썬 | - JVM 위에서 실행 - Java 라이브러리 사용 가능 - Java와의 통합 용이 |
IronPython | .NET 기반 파이썬 | - CLR(Common Language Runtime) 기반 - C# 라이브러리와 상호운용 |
초보자는 CPython만 알고 시작해도 충분합니다. 나중에 성능이 중요해지면 PyPy 등을 알아보세요.
일반적인 개발 → CPython
고성능 연산 / 반복 작업 최적화 → PyPy
Java 기반 환경과 통합 필요 → Jython
.NET 환경 연동 → IronPython
바이트코드는 사람이 읽기 어려운 중간 코드입니다.
파이썬 코드를 바이트 코드로 먼저 바꾼 후 실행됩니다.
.pyc 파일로, pycache 에 저장됨.
인터프리터(PVM)가 이를 해석하여 실행.
파이썬 코드가 바이트코드로 어떻게 바뀌는지 보려면 'dis 모듈'을 사용합니다.
import dis
def add(x, y):
return x + y
dis.dis(add)
2 0 LOAD_FAST 0 (x)
2 LOAD_FAST 1 (y)
4 BINARY_ADD
6 RETURN_VALUE
바이트코드는 '인터프리터(PVM)'가 해석하여 실행합니다.
파이썬의 인터프리터는 '스택 기반 가상 머신'입니다.
'바이트 코드'를 "스택 기반 가상 머신 방식"으로 한 줄씩 해석.
레지스터 기반이 아닌 스택 기반! -> 구현은 단순하나 속도는 느려짐. !
a = [1, 2, 3]
b = a
위 코드는 'a'라는 이름이 리스트를 가리키고,
'b'도 같은 리스트를 가리킵니다.
print(id(a), id(b)) # 같은 숫자 출력
파이썬 객체(리시트, 클래스 등)는 '힙 영역'에 저장됩니다.
변수는 객체를 직접 저장하지 않고, 참조(포인터)를 저장합니다.
struct PyObject {
Py_ssize_t ob_refcnt; // 참조 횟수
PyTypeObject *ob_type; // 타입 정보
};
import sys
a = []
print(sys.getrefcount(a)) # 참조 횟수 확인
class Node:
def __init__(self):
self.ref = self
n = Node()
import gc
gc.collect() # 수동으로 GC 실행