C 说明Windows中的虚拟内存管理器如何获取内存映射文件数据

C 说明Windows中的虚拟内存管理器如何获取内存映射文件数据,c,winapi,window,C,Winapi,Window,比方说,如果我有一个大文件映射到进程的虚拟地址空间,那么: //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 hFileMappi

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

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

BD

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


所以,当你们将数据映射到内存中时,系统不仅要从文件中读取数据,还要等到你们第一次访问它。第一次访问时-它读取的数据不是整个节范围(节不能从文件开始,也不能在文件结束时结束),而是仅访问的页面(可能是多个页面)

BD

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


所以,当你们将数据映射到内存中时,系统不仅要从文件中读取数据,还要等到你们第一次访问它。在第一次访问时,它读取的数据不是整个节范围(节不能从文件开始,也不能在文件结束时结束),而是仅访问的页面(可能是多个页面)

answer-B和Danswer-B和d
ETHREAD
结构中有几个值可能会影响在处理页面错误时作为集群读入的页面数量:
DisablePageFaultClustering
(默认值为false)和
ReadClusterSize
(默认值为7)。它似乎像预期的那样工作。我将一个线程的
ReadClusterSize
降低到3,并让它访问映射的数据文件。在本地内核调试器中,我可以看到在加载两个连续页面后,下一个
ReadClusterSize-1
页面已经有效。
ETHREAD
结构有两个值,可能会影响在处理页面错误时作为集群读入的页面数量:
DisablePageFaultClustering
(默认值为false)和
ReadClusterSize
(默认值为7)。它似乎按预期工作。我将线程的
ReadClusterSize
降低到3,并让它访问映射的数据文件。在本地内核调试器中,我可以看到在加载两个连续页面后,下一个
ReadClusterSize-1
页面已经有效。