이번 항목은 메모리를 잡기 위해서 어떤 비용을 내고, 얼마나 잡히는지 생각해 보는 계기가 될 수 있을 것이라 생각하게 해 주는 항목이다.

1 ) new나 malloc으로 메모리 n 바이트를 잡으려 할 때, n 바이트만 잡힐까?

이 질문의 대답은 "적어도 n 바이트" 이상 잡힐 수 있다로 말 할 수 있다. 왜냐하면 "관리를 위한 기록", "조각(chunck)크기에 따른 여백" 때문이다.


관리를 위한 기록은 무엇인가?

범용 메모리 관리자를 이용하여, 메모리를 잡게 되면, 얼마나 잡혔는지 기록하는데, 이 기록은 나중에 해제하고자 할 때, 얼마나 해제 할지 결정하기 위해서이다. 일반적으로 최상위 메모리 번지에 기록해 둔다.


조각(chunk)크기에 의한 여백은 무엇인가?

고정 크기로 잡기 때문에, 고정 크기보다 더 적은 량을 잡게 되면, 나머지 부분이 남는데, 이 남는 공간은 사용 할 수 없는 여백으로 남는다.


2 ) 동일한 개수의 그리고 동일한 형식 T의 객체들은 담는다고 할 때, 여러 표준 컨테이너들은 각각 어느 정도의 메모리를 사용 할까?

표준 컨테이너에서 객체를 담고자 할 때, 어느 정도의 메모리가 필요한가?

vector<T> : 개당 sizeof(T)의 메모리가 필요하다.

deque<T> : 개당 sizeof(T)의 메모리와 페이지당 메모리 포인터 4 바이트

list<T> : 개당 sizeof(T)와 앞뒤 노드를 가리킬 포인터 두개 8 바이트

set<T> : 개당 sizeof(T)와 왼쪽, 오른쪽, 부모를 가리킬 포인터 세개 12 바이트

32bit 환경에서의 포인터는 4Byte 이므로, 포인터는 4 바이트로 측정했다.


위에서 말한데로 메모리를 잡을까?

대답은 노! 실행시점 메모리 관리 전략에 따라, 달라 질 수 있다. MSVC(버전은 모르겠다)에선 고정 크기 할당 전략을 따르고, 16 바이트의 배수로 잡는다고 한다.

그렇다면, char 형, int 담을 때 어떻게 달라지는가?

list<char> 는 개당 9바이트, set<char> 13바이트 로 잡혀야 하지만, 고정 크기 전략에 의해, 16바이트 단위로 잡히니, 둘다 동일한 16바이트가 잡힌다.


총평

메모리를 적게 쓰는 컨테이너를 선택하고 싶다면, 무리해서 vector 를 쓸게 아니라... 무리해서 컴파일러 문서 부터 읽어 봐야 겠다.


posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요