개요
파이썬에서 리스트가 메모리에 배치되었을 때 아래의 그림처럼 할당된 리스트의 마지막 이후처럼 메모리가 사용되고 있을때 리스트의 요소가 추가 되었을 때 어떻게 메모리가 할당 되는가에서 나온 궁금증이다.
일단 파이썬의 리스트 요소들은 연속적인 메모리 주소를 가지지 않는다는 것을 말하고 다음으로 넘어가려고 한다.
파이썬의 리스트 특징
- 리스트를 선언할 때 크기를 미리 정할 필요가 없다.
- 리스트를 만들 때 저장할 데이터의 타입을 사전에 정하지 않아도 된다.
- 한 리스트에 다양한 타입의 데이터를 함께 저장할 수 있다.
파이썬 리스트의 저장 구조
- 리스트는 이중 포인터가 리스트 요소의 주소를 가지는 배열을 가리키고 주소가 요소를 가리키는 구조로 구현된다.
- 각 요소는 메모리 상에서 서로 다른 위치에 있을 수 있기 때문에 연속적인 메모리 주소를 가지지 않을 수도 있다.
- 추가적으로 위의 그림처럼 이중 포인터 구조로 이루어져 있기 때문에 초기 선언시 자료형을 지정하지 않아도 되고, 하나의 리스트 안에 서로 다른 자료형을 저장할 수 있는 것이다.
파이썬 리스트 메모리 할당
- 동적배열로 구성되기 때문에 초기 선언시 크기 지정이 필요하지 않다.
- 초깃값을 작게 잡아 배열을 생성하고, 리스트가 꽉 채워지면 크기를 늘려주는 방식(더블링) 으로 동작한다.
# 더블링 동작 구현코드
# The growth pattern is: 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, ...
# Note: new_allocated won't overflow because the largest possible value
# is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3;
# Do not overallocate if the new size is closer to overallocated size than to the old size.
메모리 할당의 안전성: 코드에 따르면 new_allocated가 오버플로우를 일으키지 않음을 보장합니다. 최대 가능한 값은 PY_SSIZE_T_MAX * (9 / 8) + 6이며, 이는 항상 size_t 형으로 표현 가능한 범위에 있습니다.
이 방식을 통해 파이썬 리스트는 요구되는 메모리를 점진적으로 조정하면서도, 메모리 낭비를 최소화하고, 프로그램의 요구에 유연하게 대응할 수 있는 구조를 가지게 됩니다. 이런 메모리 할당 로직은 파이썬 리스트의 성능 최적화에 중요한 역할을 합니다.
결과
결과적으로 파이썬에서 리스트의 요소가 추가되었을 경우에는 용량이 없으면 크기를 늘리고 추가되며, 파이썬에서 리스트는 위에서 설명한 이중 포인터 구조를 가지기 때문에 메모리 할당은 연속적이지 않을 수 있다.
참고
https://daebaq27.tistory.com/27
'Language > Python' 카테고리의 다른 글
[Python]GIL 너는 대체 머냐? (0) | 2024.04.15 |
---|---|
[Python]파이썬의 숨겨진 심장박동, 레퍼런스 카운팅 (0) | 2024.04.15 |
[Python]파이썬은 모든것이 객체? (0) | 2022.08.22 |
[Python] 함수 인자 전달 방식 - Call by assignment (0) | 2022.08.22 |