http://valley.egloos.com/viewer/?url=http://byung.egloos.com/4812368
골치 아픈 Memory Fragmentation
Application Debugging을 하다 보면, 간간히 들어오는 Issue가 OOM(Out Of Memory)에 대한 이슈인데, 이거 생각보다 골치가아프다. 사실 이를 위해서 DebugDiag 나 UMDH 라는 훌륭한 Tool에 의지하며, Allocation pattern을 Check 하는 것은debugging도 아니지만, 눈에 띄는 Allocation pattern이나 메모리상에 보유하는 있는 실제 Allocation(Committed) region이 그다지 높지 않은 데도 불구하고 OOM현상이 발생할 수 있다는 데에 어이없어 질 때가 있다. 그러면서 Application 개발자는 분명히Allocation/release 를 엄격하게 지켰을 뿐인데... 라고 말하기도 한다. 이런 경우 무엇을 할 수 있을 까.
이는 Memory Fragmentation 현상으로 판단한다. 상당히 자잘한 Memory Alloc이 셀 수 없이 반복되면서 메모리 조각화가 발생하는 것이다. 간혹, 큰 메모리 덩어리가 할당/해제 되기도 하고 그러면서 메모리 조각화는 더 할당 받을 수 있는 free 영역이 있음에도 불구하고 !address를 Check해보면, 연속된 여분의 메모리 블럭이 존재하지 않아서 OOM을 유발하게끔 한다. 이러한 경우에 일차적으로 할 수 있는 것은 1) 어찌됐든 불필요한 작고 많은 memory 조각들이 Leak으로 존재하는 부분을 제거해야만 한다.이는 DebugDiag의 Leak tracking을 통해서 Checking될 수 있다. DebugDiag에서 제공하는 Leak 분석에서 제공하는 Callstack 정보는 그 메모리 보유 Size가 크지 않더라도 Allocation Count를 Check하여 메모리상에 산재됨으로 인한 Fragmentation의 원인이 되진 않는 지 Check 해볼 수 있다.
2) 두 번째는 문서 http://support.microsoft.com/kb/315407 에서 제공하는 registry key, HeapDecommitFreeBlockThreshold 가 도움이 될 수 있다. 이는 레지스트리에 설정된 값 이상이 되는 경우가 아니면, 재사용을 위해 decommitted 되지 않는 상태로 유지하는 것이다.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
HeapDecommitFreeBlockThreshold REG_DWORD - 0x00040000 (권고)
3)사실 2번째 방법이 Application을 위해서 얼마나 효율적인지 경험해보진 못했다. 아마도 Windows XP/2003에서 도입된 LFH (Low Fragmentation Heap)을 사용하도록 Application을 구성하는 것이 가장 효율적일지 모르겠다. 이는 문서http://msdn.microsoft.com/en-us/library/aa366750.aspx 에도 언급되었지만, HeapSetInformation API를 이용해서HeapCompatibilityInformation(0) 값을 parameter로 전달함으로써 Application Level에서 설정할 수 있다. http://msdn.microsoft.com/en-us/library/aa366705(VS.85).aspx 문서에는 다음과 같은 예제를 확인할 수 있다. 이는 Application에서 사용하는 모든 Heap을 LFH를 사용하도록 설정할 수 있다.
HANDLE heaps[1025];
DWORD nheaps = GetProcessHeaps(1024, heaps);
for (DWORD i = 0; i < nheaps; i++) {
ULONG HeapFragValue = 2;
HeapSetInformation(heaps[i],
HeapCompatibilityInformation,
&HeapFragValue,
sizeof(HeapFragValue));
}
이러한 것들이 Memory Fragmentation을 위해 도움이 될 듯 하다.
'운영체제 & 병렬처리 > 시스템프로그래밍' 카테고리의 다른 글
캐쉬 미스와 페이지 폴트를 줄이는 방법, Array (0) | 2017.01.05 |
---|---|
프로세스 힙, CRT 힙 에 LFH(Low fragmentation Heap) 생성방법 (0) | 2013.09.27 |
윈도우 힙 || CRT 힙 (0) | 2013.09.27 |
HeapSetInformation 메모리 풀 (0) | 2013.09.27 |
GlobalMemoryStatus() , GlobalMemoryStatusEx() - 컴퓨터 메모리 체크 (0) | 2013.09.25 |