[Memory] 클래스 상속 기반의 메모리 풀을 이용한 프로파일링

Binceline 2014. 2. 1. 17:12

흠흠... 메모리풀 구현한 것을 적용한 경험을 적은 글.


클래스 내부에 아무것도 존재하지 않을 경우, c++ 표준에서는 new로 할당할 메모리 크기에 0이 들어왔다면(클래스 내부에 어떤 데이터도 가지고 있지 않다면) 할당할 메모리를 1로 변경해준다고 한다. 1을 할당하고, 내가 만들 메모리 풀 자체에서는 메모리 할당 시 8바이트의 메타데이터를 저장하기 위한 공간을 확보한다. 그래서 총 9바이트가 할당되었다.

(사실 allocated인데..오타)


이것은 가상함수를 넣었을 때이다. 가상함수 테이블을 생성하기 위한 메모리를 4바이트 할당받는 것이다. 이를 생각해 보면 정말로 데이터를 가지고 있지 않은 클래스는 메모리가 필요하지 않나보다(정확히 가상함수 테이블 크기인 것을 보면).

여하튼 메모리 풀은 8바이트를 추가로 할당받으므로 12바이트가 되었다.


- 처음엔 malloc을 후킹하려 했지만 아직 malloc 내부를 잘 몰라서 포기. 

- 그 후 new 오버로딩을 이용하려 했지만 Operator new는 생성자 호출과 가상함수 테이블을 만들어 주지 않으므로 실패.

물론 placement new를 사용해 malloc을 이용해 메모리만 할당해 놓고 new 함수들을 이용해 가상함수테이블과 생성자를 호출해 줄 순 있지만, 전역 new 오버로딩을 하려고 한다면 메모리 풀 내부의 new도 모두 그것으로 바뀌고.. 무엇보다도 다른 라이브러리와 충돌을 일으킬 수 있다.

- Effective c++과 More Effective C++을 읽어보니 웬만하면 하지 말라고 써 있음.


맨 처음 생각했던 것이지만.. 원하는 객체만이라도 프로파일링이 가능하도록 만들기 위해 클래스 상속 기반의 프로파일러를 만드는 것이었다. 메모리 풀은 c++ 표준 new와 malloc을 사용하면 되고, (필요하다면 메모리 풀 자신의 operator new를 오버로딩하면 될 것이다.) 즉 A라는 클래스 내부에 new/delete 오버로딩 버젼을 만들어 두고 그 내부에서 나의 메모리 풀을 이용해 Alloc/Free 를 사용한다. 그리고 이 클래스를 상속받는 클래스는 프로파일링이 가능해진다.


다음은 2014 hsb_project에서의 메모리 풀 구현이다. 생성자/소멸자가 정상적으로 호출되고.. 메모리 체크도 되고.. 프로그램이 종료될 때 누수된 메모리를 자동으로 해제시켜 준다. 스마트 포인터를 사용해도 잘 동작함. 또 어떤 문제가 있을까?


반응형