개요
안녕하세요.
이번 글에서는 Python의 Memory 관리에 대해 살펴보겠습니다.
참고로 현재 글은 CPython(Cython)을 바탕으로 작성되었으며 Pypy, Jython 등은 다른 동작을 보일 수 있습니다.
파이썬 메모리 구조
파이썬은 크게 stack과 heap을 사용합니다.
stack은 임시로 필요한 지역 변수 등의 데이터를 저장하는데 사용됩니다.
반면 heap은 계속해서 사용해야하는 객체나 동적 할당 메모리 등의 데이터에 적합합니다.
각각의 특징을 다음 표를 통해 정리했습니다.
구분 | stack | heap |
---|---|---|
예시 데이터 | 지역변수 | 동적 할당 메모리 |
속도 | 빠르다 | 느리다 |
데이터 생성한 함수나 코드 | 종속(종료되면 할당 해제) | 독립(종료와 무관하게 할당 유지) |
할당 타입 | 원시 데이터 타입(int, float, bool 등) | 원시 데이터 타입 외(list, set, dict 등) |
파이썬의 스택과 힙 동작 예시
한편, 파이썬은 모든 객체가 heap에 생성되므로 int, float, bool 등이 heap에도 생성됩니다.
이러한 객체에 대한 참조를 보유하는 변수는 스택에 생성됩니다.
다음 예시를 통해 동작을 살펴보겠습니다.
① 메모리 할당
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1. 변수 a 할당
a = 123
print("id(a):", id(a))
print("====================")
# 2. 변수 b 할당
b = a
print("id(a):", id(a))
print("id(b):", id(b))
print("====================")
# 3. 변수 a 값 변경 (재할당)
a = a - 23
print("id(a):", id(a))
print("id(b):", id(b))
print("====================")
가장 먼저 heap의 123을 참조하는 변수 a를 stack에 할당합니다.
변수 b는 변수 a와 같은 값을 참조하도록 할당합니다.
마지막으로 변수 a의 값을 변경한다면 heap에서 100을 참조하도록 변경합니다.
② 함수에서의 메모리 할당
1
2
3
4
5
6
7
8
9
def func1(x):
x = x + 20
y = func2(x)
return y
y = 10
z = func1(y)
print("y:", y)
print("z:", z)
heap의 10을 참조하는 변수 y를 stack에 할당합니다.
func1 함수를 호출하면 해당 함수에 속한 지역변수가 할당됩니다.
func1의 변수 x는 10을 참조하며 func1의 변수 y는 30을 참조합니다.
func1이 변수 y를 반환하면 해당 함수에 속한 변수들은 할당 해제됩니다.
func1이 반환한 값을 통해 heap의 30을 참조하는 변수 z가 stack에 할당됩니다.
작은 사이즈의 객체
한편 파이썬에는 작은 사이즈의 객체를 효율적으로 관리하기 위해 python object allocator가 존재합니다.
해당 내용은 해외의 포스트 내용을 간단하게 정리했습니다.
① block
512byte보다 작은 객체를 저장하기 위한 고정된 길이의 기본 단위입니다.
다음과 같이 8byte 단위로 할당됩니다.
요청 바이트 | 할당 바이트 | class idx 크기 |
---|---|---|
1-8 | 8 | 0 |
9-16 | 16 | 1 |
… | … | … |
505-512 | 512 | 63 |
② pool
같은 크기의 block으로 구성된 단위입니다.
pool의 크기는 메모리 페이지와 동일합니다.
객체가 할당 해제되면 메모리 관리자는 그 공간을 같은 크기의 새로운 객체로 대체할 수 있습니다.
참고로 pool과 block은 메모리에 직접 할당되지 않고 다음에 나오는 arena의 미리 할당된 공간을 사용합니다.
③ arena
arena는 64개의 pool을 제공할 수 있는 메모리 단위입니다.
마무리하며
이 글에서는 파이썬의 메모리를 살펴보았습니다.
파이썬의 메모리 구조는 크게 스택과 힙으로 이루어져있습니다.
그 중 크기가 작은 객체는 arena - pool - block에 나눠 저장합니다.
그동안 가볍게 사용했던 파이썬의 메모리와 관련하여 알아보는 좋은 시간이었습니다!
감사합니다. 😀
참고 문헌
- Memory management in Python, https://rushter.com/blog/python-memory-managment/
- 메모리 관리, https://docs.python.org/ko/3/c-api/memory.html
- cpython_obmalloc.c - python_cpython, https://github.com/python/cpython/blob/ad051cbce1360ad3055a048506c09bc2a5442474/Objects/obmalloc.c#L534
Comments powered by Disqus.