我终于找到了一种方法,这个方法来源于一个帖子。诀窍在于对需要取消分配的范围使用VirtualUnlock (); 尽管此函数返回错误0x9e(“段已解锁”),但实际上释放了内存,即使页面被修改(文件正确更新)。
这是我的示例测试程序:
#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";
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;
}
printf("Mapped.\n"); getenter();
for( int n = 0 ; n < 10000 ; n++ )
{
map_ptr[n*4096]++;
}
printf("Used.\n"); getenter();
if( !VirtualUnlock( map_ptr, 5000 * 4096 ) )
{
fprintf( stderr, "VirtualUnlock() error 0x%08x\n", GetLastError() );
getenter();
UnmapViewOfFile(map_ptr);
CloseHandle(map_handle);
CloseHandle(hfile);
return 1;
}
printf("VirtualUnlock() executed.\n"); getenter();
UnmapViewOfFile(map_ptr);
CloseHandle(map_handle);
CloseHandle(hfile);
printf("Unmapped and closed.\n"); getenter();
return 0;
}
正如您所看到的,执行VirtualUnlock()后程序的工作集被减少了,这正是我所需要的。我只需要跟踪我更改的页面以便适当地解锁。
CreateFileMapping
的文件偏移参数是否转化为map object
消耗的内存量?我不太明白为什么这个偏移量会变成map object
的大小。我们对这个偏移量之前的字节不感兴趣。(除了由于粒度而产生的一些小片段。) - daparic