[Tip] Heap Memory
Windows 는 프로세스가 사용할 메모리를 Heap로 관리 한다. 하나의 프로세스는 여러개의 힙들을 가질 수 있으며 프로그램은 그 힙들로 부터 메모리를 할당한다. Heap는 Windows 객체이며 메모리 할당을 하기 위해서는 핸들이 필요하다. 기본 Heap의 핸들은 다음 할수를 통해 얻을 수 있다.
HANDLE GetProcessHeap(VOID) // 성공시 프로세스 힙의 핸들, 실패시 NULL 반환
한 프로그램이 기본 Heap 이외의 Heap 들을 생성 하는것이 가능하며 개별 Heap를 가질때에는 다음과 같은 장점이 있다.
1) 공평함
2) 다중 스레드 성능 향상
3) 할당의 효율성
4) 할당 해제의 효율성
5) Locality of reference에 의한 효율성
1. Heap 생성
새로운 Heap 를 생성하고자 하는 경우 초기 Heap의 크기를 정하여 HeapCreate 함수를 호출한다. HeapCreate 함수의 원형은 다음과 같다.
HANDLE HeapCreate(DWORD flOption, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
// 성공시 Heap 핸들 실패 시에는 NULL 반환
초기 Heap 의 크기는 페이지 크기의 배수로 상향 조정 된다. flOption 은 HEAP_GENERATE_EXCEPTIONS / HEAP_NO_SERIALIZE / HEAP_CREATE_ENABLE_EXECUTE 등으로 설정 할수 있다. Heap 의 최대 크기는 dwMaximumSize 로 결정된다. dwMaximumSize를 0이 아닌 값으로 설정한 경우 가상 주소 공간이 그 크기에 맞게 할당된다. 0이 아닌 값이 Heap 의 최대 크기가 된다. 0으로 설정 하는 경우 사용 가능한 가상 메모리 주소 공간에 의해 결정된다.
2. Heap 제거
Heap를 제거 하는 경우 HeapDestory 함수를 이용한다. HeapDestory 함수의 원형은 다음과 같다.
BOOL HeapDestory( HANDLE hHeap )
Heap 를 통째로 해제하면 다음과 같은 장점이 있다.
1) 자료구조 운행 코드를 작성할 필요가 없다.
2) 개별 요소를 일일이 해제하지 않아도 된다.
3) 한 번의 호출로 자료구조의 모든 요사가 해제되므로, 시스템이 Heap 를 관리하는데 시간을 낭비하지 않는다.
3. Heap 메모리 할당
Heap 영역에 메모리 블록을 얻을때에는 Heap 핸들, 블록 크기, 그리고 여러 플래그들을 지정해서 HeapAlloc 함수를 호출한다.
LPVOID HeapAlloc( HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
// 성공시 할당된 메모리 블록을 가리키는 포인터 실패시 NULL 반환
hHeap : 할당 하고자 하는 Heap 의 핸들 값
dwBytes : 할당할 메모리 블록의 크기
4. Heap 메모리 해제
Heap 영역의 메모리를 해제 할때는 HeapFree 함수를 사용한다.
BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
5. Heap 메모리 재 할당
Heap 영역의 메모리 크기를 변경 하고 싶은 경우 HeapReAlloc 함수를 이용한다.
LPVOID HeapReAlloc( HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes)
// 성공시 재할당된 블록을 가리키는 포인터, 실패 시에는 NULL 또는 예외가 반환
6. Heap 크기 확인
Heap 영역의 크기를 알고 싶은 경우 HeapSize 함수를 이용한다.
SIZE_T HeapSize( HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
7. 요약
1) CreateHeap 나 GetProcessHeap 함수를 통해 Heap 핸들을 얻는다.
2) HeapAlloc 으로 메모리 블록들을 할당한다.
3) HeapFree 로 개별 블록들 일부 또는 전체를 해제한다.
4) HeapDestory 로 Heap 을 파괴하고 Heap 핸들을 닫는다.
출처 : Windows 시스템 프로그래밍 윈도우즈 API 핵심 바이블