gpt4 book ai didi

windows - CreateFileMapping,MapViewOfFile,如何避免占用系统内存

转载 作者:可可西里 更新时间:2023-11-01 12:34:42 24 4
gpt4 key购买 nike

我正在开发一个针对桌面系统的应用程序,该系统可能只有 256MB RAM(Windows 2000 及更高版本)。在我的应用程序中,我有一个大文件 (>256MB),其中包含大约 160 字节/每个的固定记录。这个应用程序有一个相当漫长的过程,随着时间的推移,它将随机访问大约 90% 的文件(用于读取和写入)。任何给定的记录写入距离该特定记录的读取不会超过 1,000 次记录访问(我可以调整此值)。

对于此过程,我有两个明显的选择:常规 I/O(FileRead、FileWrite)和内存映射(CreateFileMapping、MapViewOfFile)。后者在具有足够内存的系统中应该更有效,但在内存不足的系统中它会换出大部分其他应用程序的内存,这在我的应用程序中是不允许的。有没有办法防止进程耗尽所有内存(例如,强制刷新我不再访问的内存页面)?如果这不可能,那么我必须求助于常规 I/O;我希望在写入部分使用重叠的 I/O(因为访问是如此随机),但文档说 writes of less than 64K are always served synchronously .

欢迎提出任何改进 I/O 的想法。

最佳答案

终于找到方法了,源自一个线程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() 后程序的工作集减少了,正如我所需要的。我只需要跟踪我更改的页面,以便在适当时解锁。

关于windows - CreateFileMapping,MapViewOfFile,如何避免占用系统内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1880714/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com