Windows 64 和 32 位可以使用 MapViewOfFile 映射的最大文件大小

Posted

技术标签:

【中文标题】Windows 64 和 32 位可以使用 MapViewOfFile 映射的最大文件大小【英文标题】:Max file size that Windows 64 and 32 bit can map using MapViewOfFile 【发布时间】:2022-01-08 04:29:40 【问题描述】:

我正在处理一个需要打开大文件(数百 GB,可能是 TB)的项目。我需要对这些文件进行更改,因此我的计划是映射文件而不是创建另一个文件、读取原始文件、进行更改然后保存。

这就是我对这个想法的看法:

    hFile = CreateFile(filename, (GENERIC_READ | GENERIC_WRITE), 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) 
        return;
    

    hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
    if (hFileMap == NULL) 
        CloseHandle(hFile);
        return;
    

    mapView = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, amount);
    if (mapView == NULL) 
        CloseHandle(hFile);
        CloseHandle(hFileMap);
        return;
    

在阅读更多MapViewOfFile 之后,似乎这是在程序虚拟地址空间中映射的。对于 64 位机器,我正在读取的最大大小为 2^64 字节(16 艾字节)。而对于 32 位,它是 2GB。

如果 64 位数字是正确的,我就不需要对文件进行任何形式的分块并创建多个视图。但是在 32 位上,如果我遇到一个很大 (>2GB) 的文件,我需要对它进行分块吗?

RAM 或 HDD 空间的数量是否也受到限制?

【问题讨论】:

合理地说,您必须以任何一种方式对文件进行分块,因为除非您有足够的内存来支持该文件,否则您将遇到问题。您可能还想使用MapViewOfFile3,这样您就可以指定相当多的映射方式,例如使用大页面来提高效率。但您可能遇到的最大障碍是物理内存不存在。 所以我需要为块大小找到一个最佳位置?我在想 500mb 之类的东西,因为这将在不同的机器上运行,而且我不知道硬件配置。 由你决定,如果你基本上可以扔掉 32 位,你可能会得到一两次演出。就个人而言,具有少于 8GB 物理内存的配置数量越来越少。但值得设置最低系统要求。同时您不想告诉您的客户他们必须关闭 chrome 才能运行您的程序。您也可以随时动态调整大小。但是使用大页面之类的东西也有助于提高访问效率。 我可以做一些我想的硬件枚举并据此计算大小。我还看到MapViewOfFile3 将 Windows 10 v1803 作为最低支持的客户端,这可能是个问题。 您的客户端是否在 ESB 或不受支持的 Windows 版本上运行?否则,这应该是一个不支持的版本。在最坏的情况下,您会退回到 MapViewOfFile2,它在 ESB 版本的 1703 上受支持 【参考方案1】:

32 位的有效限制远小于 2GB。小到什么程度就不好说了。问题是地址空间与其他内存分配、特殊系统页面和其他加载的 .DLL 共享。

例如,如果您的应用程序使用打开/保存通用对话框,那么这将加载 COM 和您可能已安装的任何第 3 方 shell 扩展(NSE、图标覆盖、上下文菜单等),并且这些 .DLL 可能会保持加载状态一段时间(有些永远不会卸载)导致您的地址空间变得碎片化,并且没有可用的大范围连续可用地址。

缓解这种情况的一种方法是在程序的早期调用VirtualAlloc 以保留一个较大的范围,可能是 500-1000MB。在映射文件之前释放保留的范围。

如果您的文件始终 > 1GB 并且您希望支持 32 位,那么您必须实现一个替代例程,该例程以较小的块进行映射。对于 64 位,地址空间非常大,您应该不会遇到缺少可用地址的问题。

将文件映射到内存不是免费的,它需要一些空闲的 RAM 用于页表。这可能是特定于架构的。

【讨论】:

对于 64 位,我仍然会受到 RAM 的限制,对吗?如果我有一个 100GB 的文件而只有 8GB 的​​内存,这会是个问题吗?如果 PC 有 4GB 或 8GB 的​​ RAM,我可能会在 32 位上运行,所以我会更想知道我需要什么文件大小来开始分块。 我不知道有多少限制,但我认为 8GB 足以映射一个 100GB 的文件。整个文件永远不会同时在 RAM 中(除非您锁定页面),内核将处理页面的换入和换出。 删除了我的 cmets 建议大页面...存在一些严重的问题,其中最重要的是默认情况下它们被禁用。这意味着@xx9000 应该认真考虑由于页表的开销而导致的窗口化。 我不熟悉窗口化。 @xx9000 窗口化只是改变了内存映射中可见的文件部分。这与分块的效果相同。

以上是关于Windows 64 和 32 位可以使用 MapViewOfFile 映射的最大文件大小的主要内容,如果未能解决你的问题,请参考以下文章

目前计算机上主流的Windows操作系统分为32位和多少位?

检测32位或64位Windows

32位机上用vs2008开发的c++程序如何能在64位系统下运行?

扫盲32位和64位Windows的区别

在 64 位 Windows 上安装 32 位或 64 位应用程序有啥区别?

从用户代理或 Javascript 检测 64 位或 32 位 Windows?