澄清Windows中虚拟内存管理器如何获取内存映射文件数据

问题描述 投票:0回答:1

比方说,如果我有一个大文件,我会映射到我的进程的虚拟地址空间:

//Error handling is omitted for brevity
HANDLE hFile = CreateFile(L"path-to\\file", 
            GENERIC_READ,
            FILE_SHARE_READ, NULL, OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
char* pAddress = (char*)MapViewOfFile(hFileMapping,
            FILE_MAP_READ, 0, 0, 0);

//And get the data
char data_byte = pAddress[offset];

//Then remember to do the cleanup ....

内核虚拟内存管理器何时从磁盘上的文件读取实际数据(或执行I / O操作以从硬盘驱动器获取数据):

A)当调用MapViewOfFile时,或

B)当我用pAddress[offset]访问它时?

第二个问题,如果上面的答案是B - 当它获取数据时:

C)是否读取整个文件,或

D)只有包围的页面(4K大小,左右)?

c winapi window
1个回答
3
投票

B和D.

当您调用MapViewOfFileZwMapViewOfSection)内核保留范围虚拟视图但不将其与真实物理页面关联时(因此不要在开始时分配物理页面)。当您第一次访问部分视图中的某个地址时 - 因为它尚未与物理页面关联(PTE无效) - cpu将生成异常。系统处理此异常时,它会分配已经存在的物理页面,将虚拟地址与此页面关联,从文件中读取数据(如果由文件支持),并从指令继续执行,从而生成异常。

因此,当您将数据映射到内存中时,系统不仅可以从文件中读取数据,还要等到第一次访问它时。并且在第一次访问时 - 它读取数据而不是整个部分范围(部分可以从文件开始和结束而不是文件结束开始)但只能访问页面(可能是几页)

© www.soinside.com 2019 - 2024. All rights reserved.