마침내 길을 찾았습니다. 스레드에서 파생되었습니다 here. 트릭은 VirtualUnlock()을 커밋하지 않아도되는 범위에서 사용하고 있습니다. 이 함수는 오류 0x9e ("세그먼트가 이미 잠금 해제 됨")와 함께 FALSE를 반환하지만 페이지가 수정 되었더라도 (파일이 올바르게 업데이트 됨) 메모리가 실제로 해제됩니다. 당신이 볼 수 있듯이
#include "stdafx.h"
void getenter(void)
{
int ch;
for(;;)
{
ch = getch();
if(ch == '\n' || ch == '\r') return;
}
}
int main(int argc, char* argv[])
{
char* fname = "c:\\temp\\MMFTest\\TestFile.rar"; // 54 MB
HANDLE hfile = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
if(hfile == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "CreateFile() error 0x%08x\n", GetLastError());
getenter();
return 1;
}
HANDLE map_handle = CreateFileMapping(hfile, NULL, PAGE_READWRITE | SEC_RESERVE, 0, 0, 0);
if(map_handle == NULL)
{
fprintf(stderr, "CreateFileMapping() error 0x%08x\n", GetLastError());
getenter();
CloseHandle(hfile);
return 1;
}
char* map_ptr = (char*) MapViewOfFile(map_handle, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0);
if(map_ptr == NULL)
{
fprintf(stderr, "MapViewOfFile() error 0x%08x\n", GetLastError());
getenter();
CloseHandle(map_handle);
CloseHandle(hfile);
return 1;
}
// Memory usage here is 704KB
printf("Mapped.\n"); getenter();
for(int n = 0 ; n < 10000 ; n++)
{
map_ptr[n*4096]++;
}
// Memory usage here is ~40MB
printf("Used.\n"); getenter();
if(!VirtualUnlock(map_ptr, 5000 * 4096))
{
// Memory usage here is ~20MB
// 20MB already freed!
fprintf(stderr, "VirtualUnlock() error 0x%08x\n", GetLastError());
getenter();
UnmapViewOfFile(map_ptr);
CloseHandle(map_handle);
CloseHandle(hfile);
return 1;
}
// Code never reached
printf("VirtualUnlock() executed.\n"); getenter();
UnmapViewOfFile(map_ptr);
CloseHandle(map_handle);
CloseHandle(hfile);
printf("Unmapped and closed.\n"); getenter();
return 0;
}
것은 프로그램의 작업 집합 VirtualUnlock는(), 내가 필요한대로 실행 한 후 감소 :
여기 내 샘플 테스트 프로그램입니다. 나는 필요한만큼 잠금을 해제하기 위해 내가 변경 한 페이지를 추적하기 만하면됩니다.
아마도 VirtualFree (MEM_DECOMMIT)가 도움이 될 수 있습니까? 나는 그것에 익숙하지 않다. –
아니요, MMF의 경우 VirtualFree (MEM_DECOMMIT)가 실패합니다. 방금 확인 했어. –