Purpose-built post
이 포스트는 "Modern C++ Design Chapter 4. 작은 객체에 대한 메모리 할당"을 읽고 내가 이해하기 위해 정리를 하며, 포스트로 남긴 것이다. - 익필
Content
1. 무엇을 메모리 풀 memory pool 이라고 하는가?
메모리 풀을 역활로 정의를 하면, 메모리 할당/해제/용량 최적화 등을 효율적으로 처리해 주는 웅덩이/수영장/도구/장치/관리자 이다. 단어 자체로 정의를 하면, 메모리 저수지 정도로 이해하면 되겠다.
pool 이라는 것을 예를 들면, 농업을 들 수 있다. 농작물을 제배하기 위해선, 물이 필요한데, 기후가 변덕을 부리어, 비가 오지 않을 때, 미리 저수지에 모아 두었던 물을 양수기로 퍼올려 농작물에 물을 공급함으로써, 효율적으로 농작물을 기를 수 있게 된다.
2. 왜 메모리 풀이 필요한가?
첫번째 이유
C/C++ 에선 메모리를 할당 하기 위해서 시스템 콜(OS 내부 함수를 요청)을 해야만 한다. 이 시스템 콜 생각보다 부하를 많이 잡아 먹는다. 이처럼 성능이 스택에 메모리를 생성 하는 것 만큼 빠르지 않으므로, 잦은 할당/해제는 많은 오버헤드를 불러 일으킨다.
두번째 이유
메모리 할당으로 4Byte 를 요구 했을 때, 실제로 4Byte 말고도, 몇 바이트를 할당 했는지, 할당한 메모리에 추가적으로 4Byte ~ 32Byte 를 추가하여 할당을 한다. 왜냐하면, 얼마 만큼 메모리를 할당했는지 기록을 해야 나중에 해제 할 수 있기 때문이다.
이는 메모리를 더 많이 사용하므로, 메모리 고갈을 불러 일으킬 수 있다. 또한 메모리 할당을 더 많이 하므로써, OS의 페이징/프레임 기법에 영향을 미칠 수도 있다. 이는 오버헤드를 불러 일으킨다.
세번째 이유
할당 해제가 잦을 수록 메모리 단편화가 일어 날 수 있다. 단편화가 일어날 경우, 메모리가 여러 곳에 흩어져 있기 때문에, 메모리를 블럭 단위로 끌고 와 처리하는 작업이 더 많이 지게 된다.
하지만...
몇년전인지는 모르겠지만, 메모리 단편화는 신경쓸 필요가 없어졌다. 프로그래밍으로 메모리 할당을 요청한다는 것은 OS에 요청하는 것인데, OS가 메모리 단편화가 일어나지 않게 프레임 기법/페이징 기법을 처리해 주기 때문이다. 만약 임베비드 환경에서, 이러한 기능이 없는 OS가 쓰인다면, 메모리 풀이 필요 할 수도 있다. : )
참조 링크
3. 다른 라이브러리가 있는데 왜 메모리 풀을 만들어야 하는가?
공부하기 위해서다. 알고 쓰는것과 모르고 쓰는건 나중에 버그가 생길 때, 그 버그를 고치는 능력 차이를 만들기 때문이다.
Digression- 실제로 new/delete가 성능에 많은 영향을 미치고 있으나, 퍼포먼스 테스트를 하기 전까지 메모리 풀을 만들지 않는게 좋다고 나는 생각한다. 왜냐하면, 실제로 어디에 병목현상이 발생 하는지 모르므로, 괜한 최적화로 쓸때없는 코드리뷰를 하게 만들 수 있기 때문이다.
- 유명하고 많이 쓰이는 메모리 풀로는 apr_pool, boost::pool 등이 있다. 그렇다고 이러한 풀들을 너무 믿는 것도 힘들다. 왜냐하면, 실제로 해당 메모리 풀을 쓰기 전까지 내가 만든 프로그램에 적합한지 모르기 때문이다.
- 내가 만든 메모리 풀을 사용하기 보다, 라이브러리에서 제공하는 메모리 풀을 사용하길 권한다. 여러가지 이유가 있지만, 다른 사람에게 설명할 때, 아예 설명할 필요가 없거나, 버그도 없고 성능도 어지간해선 내가 만든것 보다 좋기 때문이다. : )
- 멀티 쓰레드 환경에서 메모리 풀은 lock free 구조가 제일 좋다. 또한 메모리 풀에 lock 이 있어, 오히려 new/delete가 더 빠를 때도 있다. 역시 이른 최적화는 독이 될 수 있으므로, 퍼포먼스 테스터를 하기 전까진 너무 최적화 하지 마라.
- 2부에선 메모리 풀을 만들기 위해, "어떻게 메모리를 할당해야 관리 할 수 있을까?" 를 정리한다.