python에서의 메모리 관리
•
Python memory manager 에 의해 메모리가 관리
C와 Python의 할당 비교
•
c는 주소값에 변수에 주소값을 할당하지만
•
python은 변수가 참조하는 객체가 바뀐다.
x = 10일 때의 경우
•
C의 경우
◦
x = 10 을 실행
◦
x에 주소 값이 할당
◦
그 메모리에 10이라는 값이 들어가게 됨.
•
Python의 경우
◦
x = 10을 실행
◦
10이라는 Integer 객체가 메모리에 생성
◦
10의 객체가 변수 x에 의해 참조
•
3.11이하 버전에서 getrefcount메서드를 사용하면 참조하는 객체 수를 알 수 있다.
•
첫 getrefcount(10)의 출력값이 18인 이유는 파이썬 내부적으로 10이라는 정수형 객체를 이미 사용했기 때문이다.
•
x와 y를 10이라는 integer 객체를 참조하게 하자 18 -> 20 으로 증가함을 볼 수 있다.
x = x + 1
•
c의 경우
◦
메모리에서 x의 현재 값을 읽어온다.
◦
이 값에 1을 더한 값을 계산
◦
결과 값을 동일한 메모리 위치에 다시 저장
메모리 위치가 변경되지 않으며, 해당 위치의 값만 5→6으로 변환
•
Python의 경우
◦
11이라는 새로운 integer 객체가 생성되고 x는 이 객체의 주소 값을 참조
1.
x의 초기값에 1을 더한 값을 계산
2.
새로운 정수 객체 6이 생성
3.
x는 이제 새로운 정수 객체 6을 가리키도록 업데이트
x가 참조하는 객체가 변경
기존 x의 5 객체는 가비지 컬렉터에 의해 메모리에서 해제될 수 있다.
z = 10일 때의 경우
•
z라는 변수를 만들고 기존의 10의 객체를 참조
•
python은 동일한 값을 가진 객체가 이미 존재하는 경우 새로운 변수에 동일한 객체 참조를 할당함으로써 메모리 사용을 최적화한다.
•
클래스로 재참조할 경우
◦
기존의 10객체를 참조하지 않고 Car 클래스를 참조
Stack과 Heap 메모리 동작 방식
•
백그라운드 메모리 구성은 모든 프로세스가 일부 메모리와 함께 운영 체제에 의해 할당
•
마찬가지로 python 인터프리터는 실행을 위해 메모리를 할당받는다.
⇒ 이는 파이썬의 버전 및 환경 세팅에 의해 결정되고, 우리는 보통 그것에 대해 크게 걱정할 필요가 없다.
•
이 메모리는 두 영역으로 분류
◦
스택 메모리 : 기본적으로 스택 메모리로부터 메서드가 실행, 참조자
◦
힙 메모리 : 객체
y = 5 일 경우
•
5라는 int 객체는 heap 메모리에 생성
•
y라는 참조자는 stack 메모리에 생성
z = f1(y)
1.
f1( ) 함수가 스택 메모리에 저장
•
z라는 지역변수가 main 함수에 생성
•
f1 함수에 y가 참조하는 5가 전달되게 되면서 f1의 매개변수(x)는 5 객체를 지침
2.
x = x * 2에 의해 x가 10 객체를 지침
3.
y = f2(x)에 의해 f2함수를 호출
•
f1 지역변수 y가 생성되고, f2 함수가 스택 메모리에 쌓이면서 f2의 매개변수(x)가 생성
•
f2 지역변수 x는 10을 전달받으면서 x를 지침
•
x = x + 1 에 의해 11을 지침
4.
f2함수에서의 return x에 의해 y는 11을 참조
f2함수의 메모리 해제
1.
f2 함수는 return 되면서 stack memory에서 해제
2.
return y에 의해서 z는 11을 지침
3.
f1 함수는 리턴되게 되면서 stack 메모리에서 해제된다.
•
또한 f1함수의 지역변수 x도 stack 메모리에서 사라지게 되면서 10을 가리키는 참조자가 없어지게 됨.
•
10을 가리키는 참조자(래퍼런스)가 0이 되면서 heap 메모리에서 10객체도 사라지게 됨.