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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了澄清Windows中虚拟内存管理器如何获取内存映射文件数据相关的知识,希望对你有一定的参考价值。

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

//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大小,左右)?

答案

B和D.

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

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

以上是关于澄清Windows中虚拟内存管理器如何获取内存映射文件数据的主要内容,如果未能解决你的问题,请参考以下文章

Linux - 用户态内存映射 和 内核态内存映射

如何像 Windows 任务管理器中显示的那样获得可用的物理内存

操作系统内存

windows虚拟内存(win32)

虚拟化平台内存原理知多少?---浅析VMware虚拟化平台内存管理

Linux 内核 内存管理内存管理系统调用 ① ( mmap 创建内存映射 | munmap 删除内存映射 | mprotect 设置虚拟内存区域访问权限 )