You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
할당된 메모리 블록의 끝을 넘어 뒤에 기록 하는 오버런(할당된 메모리 블록의 끝을 넘어 뒤에 기록하는 것)이 발생하는 경우
할당된 메모리 블록의 시작을 넘어 앞에 기록하는 언더런(할당된 메모리 블록의 시작을 넘어 앞에 기록하는 것)이 발생하는 경우
효율을 향상시키기 위해
컴파일러가 제공하는 기본 버전의 operator new 및 operator delete 함수는 일반적인 쓰임새에 맞추어 설계된 것이다.
메모리 관리자에 대한 요구사항은 다양하다.
기본적으로 제공하는 new, delete 함수는 안정적으로 구현되어 있다.
사용자 정의 new와 delete를 사용하여 우수한 성능(빠른 속도 적은 메모리)을 낼 수 있다.
개발자가 자신의 프로그램이 동적 메모리를 어떤 성향으로 사용하는지를 제대로 이해하고 있어야 한다.
응용프로그램에 따라서는 new와 delete를 사용자 정의 버전으로 바꾸는 것만으로 성능 향상을 이뤄낼 수 있다.
동적 할당 메모리의 실제 사용에 관한 통계 정보를 수집하기 위해
할당된 메모리 블록 크기의 분포
메모리가 할당되고 해제되는 순서 (FIFO? LIFO? random?)
사용 패턴이 바뀌는지?
동적 할당 메모리의 최대량은?
메모리 관리자를 만드는 일
staticconstint signature = 0xDEADBEEF;
typedefunsignedcharByte;
void* operatornew(std::size_t size) throw(std::bad_alloc) {
usingnamespacestd;// 경계표지 2개를 앞뒤에 붙일 수 있을 만큼만 메모리 크기를 늘린다.size_t realSize = size + 2* sizeof(int);
// malloc을 호출하여 실제 메모리를 얻어낸다.void* pMem = malloc(realSize);
if(!pMem) throwbad_alloc();
// 메모리 블록의 시작 및 끝부분에 경계표지를 기록
*(static_cast<int*>(pMem)) = signature;
*(reinterpret_cast<int*>(static_cast<Byte*>(pMem) + realSize + sizeof(int))) = signature;
// 앞쪽 경계표지 바로 다음의 메모리를 가리키는 포인터를 반환returnstatic_cast<Byte*>(pMem) + sizeof(int);
}
개념적으로 보면 operator new를 직접 만드는 작업은 별로 어렵지 않다.
바이트 정렬 같은 까다로문 문제가 숨어있다.
모든 operator new 함수는 어떤 데이터 타입에도 바이트 정렬을 만족하는 포인터를 반환해야 한다.
현실적으로 잘 돌아가는 메모리 관리자를 만들기는 어렵다.
컴파일러에서도 디버깅 및 로깅을 지원한다.
new 및 delete의 기본제공 버전을 다른 것으로 대체하는 작업을 해야할 때
잘못된 힙 사용을 탐지하기 위해
동적 할당 메모리의 실제 사용에 관한 통계 정보를 수집하기 위해
할당 및 해제 속도를 높이기 위해
기본으로 제공되는 범용 할당자는 사용자 정의 버전 보다 느린 경우가 많다.
사용자 정의 버전이 특정 타입의 객체에 맞추어 설계되어 있으면 더욱 그렇다.
기본 메모리 관리자의 공간 오버헤드를 줄이기 위해
범용 메모리 관리자는 사용자 정의 관리자 버전과 비교해서 속도가 느리고 메모리를 많이 잡아먹는 경우가 많다.
크기가 작은 객체에 대해 튜닝된 할당자를 사용하면 오버헤드를 제거할 수 있다.
기본 할당자의 바이트 정렬 동작을 보장하기 위해
x86 아키텍처에서는 double이 8바이트 단위로 정렬되어 있을때 읽기 쓰기 속도가 빠르다.
컴파일러 중 기본적으로 제공되는 operator new 함수가 double에 대한 동적 할당 시에 8바이트 정렬을 보장하지 않는 것이 있다.
기본제공 operator new 대신 8바이트 정렬을 보장하는 사용자 정의 버전으로 바꿀 수 있다.
임의의 관계를 맺고 있는 객체들을 한곳에 나란히 모아 놓기 위해
자료구조를 별도로 담을 별도의 힙을 생성해서 이들이 가능한 적은 페이지를 차지하도록 할 수 있다.
메모리 군집화는 위치 지정 new 및 위치지정 delete를 통해 구현할 수 있다.
원하는 동작을 수행하도록 하기 위해
응용프로그램 데이터의 보안 강화를 위해 해제한 메모리 블록에 0을 덮기 위해 사용자 정의 버전을 구현할 수 있다.
공유 메모리를 조작하는 C API에 C++옷을 입히는 위해 사용자 정의 버전을 구현할 수 있다.