VirtualAlloc함수의 Allocation Granularity에 대하여...
글쓴이: superdma / 작성시간: 금, 2009/08/21 - 3:09오전
윤성우씨의 윈도우즈 시스템 프로그래밍 책을 보다가 VirtualAlloc 함수 부분이 헷갈려 글남깁니다.
VirtualAlloc 함수의 첫번째 인자값에 대한 설명은
"예약 및 할당하고자 하는 메모리의 시작 주소를 지정한다.
일반적으로 NULL을 전달 하게 되는데, NULL이 전달되면 할당하고자 하는 크기에 맞춰서 메모리의 위치를 임의로 결정한다.
그러나 RESERVE상태에 있는 페이지를 COMMIT 상태로 변경할 떄에는 해당 페이지의 시작주소를 지정해야 한다.
예약을 할 때에는 'Allocation Granularity Boundary'를 기준으로 값이 조절되고, 할당을 할 때에는 페이지 크기 단위로 값이 조절된다(내부적으로 계산)" 이라고 나왔습니다.
각각 예약을 할 때에는 'Allocation Granularity Boundary'를 기준으로 값이 조절되고, 할당을 할 때에는 페이지 크기 단위로 값이 조절된다 라고 되어있는데, Allocation Granularity은 어디에 영향을 끼치는 겁니까?
현재 예약 메모리 크기를 정하는 건, 27줄에 있는 VirtualAlloc의 2번쨰 인자인 MAX_PAGE * pageSize(10*4096 byte)인데 여기서 'Allocation Granularity은 어떤 기준이 되는건가요?
/* DynamicArray.cpp */ #include <stdio.h> #include <stdlib.h> #include <windows.h> #define MAX_PAGE 10 // 할당할 최대 페이지 개수. int* nextPageAddr; DWORD pageCnt = 0; DWORD pageSize; int PageFaultExceptionFilter(DWORD); int main(int argc, TCHAR *argv[]) { LPVOID baseAddr; int* lpPtr; SYSTEM_INFO sSysInfo; GetSystemInfo(&sSysInfo); pageSize = sSysInfo.dwPageSize; // 페이지 사이즈 참조. // MAX_PAGE의 개수만큼 페이지 RESERVE! baseAddr = VirtualAlloc( NULL, // 임의 주소 할당. MAX_PAGE * pageSize, // 예약 메모리 크기. MEM_RESERVE, // RESERVE! PAGE_NOACCESS); // NO ACCESS. if (baseAddr == NULL ) _tprintf(_T("VirtualAlloc reserve failed")); lpPtr = (int*) baseAddr; // 배열의 시작번지와 같은 의미 부여. nextPageAddr = (int*) baseAddr; // page fault 발생시 예외 발생. for (int i=0; i < (MAX_PAGE * pageSize) / sizeof(int); i++) { __try { // Write to memory. lpPtr[i] = i; } __except ( PageFaultExceptionFilter( GetExceptionCode() ) ) { // 적절한 예외처리(페이지 할당)가 이뤄지지 않으면 프로세스 종료! ExitProcess( GetLastError() ); } } //for(int i=0; i < (MAX_PAGE * pageSize) / sizeof(int); i++) // _tprintf(_T("%d "), lpPtr[i]); // 메모리 해제 BOOL isSuccess = VirtualFree( baseAddr, // 해제할 메모리의 시작번지. 0, // 세번째 인자가 MEM_RELEASE 이므로 반드시 0. MEM_RELEASE); // FREE 상태로 변경. if(isSuccess) _tprintf( _T("Release succeeded!")); else _tprintf( _T("Release failed!")); } int PageFaultExceptionFilter(DWORD exptCode) { // 예외의 원인이 'page fault'가 아니라면. if (exptCode != EXCEPTION_ACCESS_VIOLATION) { _tprintf( _T("Exception code = %d \n"), exptCode); return EXCEPTION_EXECUTE_HANDLER; } _tprintf( _T("Exception is a page fault \n")); if (pageCnt >= MAX_PAGE) { _tprintf( _T("Exception: out of pages \n") ); return EXCEPTION_EXECUTE_HANDLER; } LPVOID lpvResult = VirtualAlloc ( (LPVOID) nextPageAddr, // next page to commit pageSize, // page size, in bytes MEM_COMMIT, // allocate a committed page PAGE_READWRITE // read/write access ); if (lpvResult == NULL ) { _tprintf( _T("VirtualAlloc failed %d \n")); return EXCEPTION_EXECUTE_HANDLER; } else { _tprintf ( _T("Allocating another page. \n") ); } pageCnt++; nextPageAddr += pageSize/sizeof(int); // page fault가 발생한 지점부터 실행을 계속. return EXCEPTION_CONTINUE_EXECUTION; }
Forums:
댓글 달기