파이썬에 대한 기본적인 이해를 위해 작성했습니다
다음 블로그를 참고했습니다.
https://dc7303.github.io/python/2019/08/06/python-memory/
[Python] 파이썬의 메모리 관리
인스타그램이 GC를 사용하지 않은 뒤 성능이 10%정도 향상 됐다는 글을 봤습니다. GC가 어떻게 동작하는지 궁굼하기도 했고 평소 파이썬으로 프로그래밍 하는 걸 좋아하기 때문에 깊게 이해해보
dc7303.github.io
#1 변수는 메모리 레퍼런스
누군가에게 편지를 보낼 때는 보통 편지에 주소를 적어야 한다.
그 주소는 세계 어딘가에 있는 특정 우체통과 일치해야 할 것이다.
특정 우체통의 주소를 써서 편지 내용을 우편함에 확실히 전달한다.
컴퓨터와 메모리도 이와 비슷하다.
데이터가 저장되는 슬롯마다 고유한 주소가 필요하다.
저장되는 객체는 하나 이상의 슬롯을 차지할 가능성이 높다.
객체가 저장되기 시작한 시작 주소만 알면 해당 객체에 접근할 수 있다.
이렇게 저장되는 슬롯들의 공간이 "힙"이다.
힙에 객체를 저장하고 가져오는 것은 Python 메모리 매니저가 알아서 한다.
my_var_1 = 10
10이라는 값은 특정 주소값의 슬롯에 저장된다.
여기서 해당 주소값을 임의로 0x1000이라고 가정하자.
그러면 my_var_1은 0x1000에 있는 객체의 참조라고 할 수 있다.
즉, my_var_1은 10이 아니다.
my_var_1은 메모리 주소 0x1000에 위치한 10이라는 값이 포함된 정수 객체에 대한 참조
파이썬에서는 id() 함수를 사용하여 변수가 참조하는 메모리 주소를 찾을 수 있다.
id() 함수는 10진수로 반환하며, hex() 함수를 사용하면 16진법으로 변환할 수 있다.
#2 Reference Counting & Garbage Collection
Referenece Counting
레퍼런스 카운트 전략이란 파이썬의 모든 객체에 카운트를 포함하고, 이 카운트는 객체가 참조될 때 증가하고, 참조가 삭제될 때 감소시키는 방식으로 작동됩니다. 이때 카운터가 0이 되면 메모리가 할당이 삭제됩니다.
객체를 참조할 때마다 해당 객체의 레퍼런스 카운팅이 증가한다.
다음과 같이 변수가 선언되었다고 생각해 보자
my_var_1 = 10
my_var_2 = my_var_1
위 경우 10이라는 값이 포함된 정수 객체의 레퍼런스 카운팅은 2가 된다.
이후 해당 변수가 다른 객체를 참조하거나 삭제되는 경우 카운팅은 줄어들며, 0이 되는 순간 해당 메모리가 지워진다.
하지만, 레퍼런스 카운팅에서는 순환 참조에 의해 메모리 누수가 발생할 수 있다.
my_var = ObjectA()
ObjectA라는 객체를 참조한다.
하지만, 해당 객체의 속성값(var_1)이 ObjectB를 참조한다고 생각해 보자.
그러면 my_var가 삭제되는 순간 ObjectA의 레퍼런스 카운트가 0이 되어 메모리가 반환된다.
그 순간 var_1이 삭제되고 ObjectB의 레퍼런스 카운트가 0이 되어 메모리가 반환된다.
여기 까지는 문제가 없는데, ObjectB의 속성값(var_2)이 ObjectA값을 참조하는 경우 어떻게 될까?
my_var가 삭제되는 순간 ObjectA의 레퍼런스 카운트는 0이 아닌 1이 된다.
즉, 해당 객체를 참조하고 싶지 않은 상태인데 참조되고 있는 상태가 되며 메모리 누수가 발생하는 것이다.
이를 순환 참조 라고 한다.
이러한 메모리 누수를 해결하기 위해서는 Garbage Collector(이하 GC)가 필요하다.
GC는 순환 참조를 식별하고, 처리할 수 있다.
Garbage Collection
GC는 gc module을 이용해 프로그램적으로 제어된다.
기본값으로 켜져 있으며, 임의로 끌 수 있다. 하지만 순환 참조가 발생하지 않는다는 보장 하에 꺼야 한다.
왜 꺼야 하는 경우가 발생할까?
GC는 기본적으로 1분 주기로 순환 참조를 확인한다.
확인하며 부하가 발생하기 때문에 성능이 저하될 수 있다.
'TIL (Today I Learned) > Python' 카테고리의 다른 글
[Python] 변수와 메모리 #3 (0) | 2023.04.05 |
---|---|
[Python] 변수와 메모리 #2 (0) | 2023.04.03 |
[Python] Classes (0) | 2023.04.02 |
[Python] For loop (0) | 2023.04.02 |
[Python] While loop (0) | 2023.04.02 |
댓글