강좌

C++ boost 메모리풀 강좌 #3: singleton_pool 클래스를 이용하여 일반 클래스에 메모리풀 적용하기

하늘흐늘 2021. 11. 13. 14:16
반응형

singleton_pool 클래스도 기본적으로 이전에 설명한 pool과 비슷합니다. 이 클래스는 템플릿 주요 인자로 할당 크기를 구분하는 태그 인자와 할당 크기를 받습니다. 태크 인자와 할당 크기라는 인자 특성 때문에 일반 클래스에 operator new / delete를 재정하여 적용하기에 쉽습니다. 이 외에 singleton_pool은 기본적으로 멀티쓰레드에서 안전합니다. 싱글쓰레드에서 사용할 때는 성능을 올리기 위하여 mutex 인자 부분에 boost::details::pool::null_mutex을 넣어주면 좋습니다.

간단한 사용법 예를 살펴보겠습니다.

#include <iostream>
#include <boost/pool/singleton_pool.hpp>

using namespace std;

template< class T >
class memory_pool_alloc
{
public:
	static void* operator new(std::size_t size)
	{
		assert(sizeof(T) == size);

		return boost::singleton_pool< T, sizeof(T) >::malloc();
	}

	static void operator delete(void* p)
	{
		boost::singleton_pool< T, sizeof(T) >::free(p);
	}

	static void purge_memory()
	{
		boost::singleton_pool< T, sizeof(T) >::purge_memory();
	}
};

class test_mpa : public  memory_pool_alloc<test_mpa>
{
private:
	char test_[256];

public:
	void test()
	{
		strcpy_s(test_, 256, "hello, singleton_pool");

		cout << test_ << endl;
	}
};

int main(int argc, char* argv[])
{
	test_mpa* test = new test_mpa();

	test->test();

	delete(test);

	test_mpa::purge_memory();

	return 0;
}

boost::singleton_pool 클래스는 싱글톤인 관계로 템플릿 인자들을 맞게 넣어준 뒤 할당과 해제에 따라 malloc과 free를 예에서 처럼 해주면 됩니다. 실용적인 클래스가 예제에 포함된 관계로 예에서 처럼 memory_pool_alloc<{class name}>와 같이 상속 받으면 어떤 클래스에서나 메모리 풀이 적용됩니다.

assert(sizeof(T) == size); 코드 부분을 넣어준 이유는 다음과 같습니다.
memory_pool_alloc<T>을 상속받은 test_mpa를 또 다른 x클래스가 상속받는다고 가정하여 봅시다. operator new는 상속되기 때문에 x클래스에서 새롭게 operator new를 재정의하지 않는 이상 잘못된 메모리 크기가 할당되어 메모리 관련 문제를 일으킬 수 있습니다. assert는 이런 문제가 발생할 때 체크하기 위함입니다. 

마지막으로 메모리풀을 다 사용한 후에는 명시적으로 purge_memory() 해주어야 합니다. MFC와 같은 경우는 사용 후에 purge_memory()를 해주지 않으면 프로그램 종료 후 메모리풀을 사용한 메모리를 memory leak으로 검출합니다.

참고적으로 메모리풀에서 사용하지 않는 메모리를 해제시키는 release_memory() 함수도 알아두면 좋습니다.


반응형