메모리는 할당과 해제를 반복할수록 하드디스크와 동일하게 단편화(조각으로 나눠지는 현상)가 일어나게 되는데
이런 이유로 대부분의 운영체제들은 내부적으로 메모리를 최적화하는 자체 구현을 가지고 있다.
속도와 메모리관리의 효율성을 우선시하는 대형 프로그램(수백개의 객체들이 수시로 나타났다 사라지는
온라인 게임 같은 경우가좋은 예다)들은 자체적으로 메모리 관리자를 가진다.
간단히 설명하자면 이런식의 구현이다.
1. 실행전 사용가능한물리적 메모리 범위내에서가능한 크게 메모리 영역을 미리 잡는다.
-이 단계에서 실패하면 실행이 안되거나 경고를 내보낸다
2. 해당 영역에 고정적으로 사용하는 객체들을 배열한다.
3. 객체 크기가변하지 않는 객체들 끼리는사용이 종료 되더라도 메모리 영역을 해제하지 않고
동일 크기나 비슷한 크기의 객체가 할당을 요구할 때 재사용한다.
이것으로써 얻을 수 있는 잇점은..
1. 메모리 할당과 해제에 시간이 걸리지 않는다(운영체제 api 사용 안함)
2. 단편화가 일어나지 않는다(동일 사이즈의 객체는 할당을 해제해도 그 영역을 유지한다)
각설하고.. 파이썬의 메모리 관리자 역시 위와 비슷하다.
파이썬에서는모든 객체가 참조카운트를 가지고 있고
어디선가 그 객체의 내용을 참조하거나 변경하는 곳이 있을 경우 1씩 증가한다.
반대로 더이상 사용하지 않는 경우(예컨데해당 변수에 새로운 객체를 할당하면)
참조카운트(레퍼런스 카운트)가 -1 씩 되며, 0 까지 내려가면 해당 객체는 지워지게 된다.
a = test() #test 의 참조 1 로 증가
b=a # test 의 참조 2 로 증가
a = None #test 의 참조 1 로 감소
b= None #test 의 참조 0 으로 감소, 이 지점에서 test() 의 파괴자가 호출된다.
만약 위에 c = a 가 한줄 더 있었다면, c 의 참조가 없어질 때까지 test 의 인스턴스는
유지된다.
위에서 봤다시피 어딘가의 다른 변수에서 test 을 참조하고 있다면...
설령 그 객체가 프로그램 실행중 한번도 사용되지 않더라도 test객체의 인스턴스는
절대 해제되지 않는다.
2005 년 이전의 파이썬은, 객체가 해제 되더라도 운영체제로 메모리를 반환하지 않는 구조를 가져서
문제가 됐었던 적이 있었다.
물론 현재의 파이썬의 메모리 관리자는 좀 더 진일보한 것이여서 그러한 문제는 줄어들었다.
하지만 그렇다 하더라도 메모리의 효율성 측면에서는C/C++ 에서의 수동메모리 관리보다는
조금 아쉬운 면이 있다.