C3859:超出 PCH 的虚拟内存范围

C3859: Virtual memory range for PCH exceeded

我时常(不是每次)收到此错误消息我编译(编辑:抱歉,我在这里没有说清楚:我实际上是指 "rebuild")我的混合模式项目。 Visual Studio 告诉我 "recompile with a command line option of '-Zm114' or greater"。原则上没问题,我照VS说的做。

但是目前,这有两个问题:

  1. 为什么每次我都重建了?如果我理解正确,编译器 运行 在编译我的项目时内存不足。因此,如果我进行重建,清理所有之前的工作,那么下次我不更改任何内容时,它不应该 运行 内存不足吗?

  2. 为了安全起见,我已经在这个项目的所有配置中为Zm指定了120的值(即Zm120)。为什么我会收到带有此较低值的错误消息?还是建议值 114 只是 VS 的胡乱猜测?

我知道这已经过时了,但我最终来到这里,所以我不妨回答一下。

有一篇关于 PCH 问题的好文章 here

1) 为什么每次重建时都不会出现?
肯定地回答这个问题有点复杂。由于它并非每次都发生,因此可能是几个问题。这很可能是由于内存分配。来自文章:

  • Fragmentation of the virtual memory address range(s) required by the PCH before CL.EXE is able to load it into memory.
  • Failure of the Windows OS under heavy loads to increase the pagefile size within a certain time threshold.

也可能是页面文件大小问题(最有可能在虚拟机上),但我相信您会收到类似这样的消息:

c1xx : error C3859: Failed to create virtual memory for PCH [...Project.vcxproj] c1xx: note: the system returned code 1455: The paging file is too small for this operation to complete

2) 为什么我会收到一条错误消息,其中包含这个较低的值? (Zm114 而不是 Zm120)
确保 Zm120 修改处理所有构建配置(发布|调试)和平台(x86|x64)。

将 PreferredToolArchtecture 设置为 x64 也有帮助:

If you’re using MSBuild from the command line you can pass /p:PreferredToolArchtecture=x64 to MSBuild. If you’re building with MSBuild from within Visual Studio, you can edit your .vcxproj file to include a PropertyGroup containing this property.

这个很容易被忽略,但是当预编译头太大时也会出现这种问题。做一点清理也可能是个好主意。

只是插话一下解决方案最终对我来说是什么。似乎 Visual Studio 试图为多种架构编译我的程序,尽管我认为我已经删除了配置文件,但配置管理器中有一堆虚假条目以 x86 模式构建。这些对我没用,因为我只想在 x64 中构建。删除这些条目后,程序再次编译,此错误消失了。希望对大家有帮助。

这个问题的另一个原因。我不是 crystal 清楚项目是如何进入这种情况的,但它试图使用 PCH 文件,将 "Precompiled Header File" 选项设置为 pch.h,但是 "Precompiled Header Output"下面的选项是空的。

这并不奇怪,但是 Visual Studio 对此非常不满,特别是在构建过程中抛出了许多 C3859 错误。

将项目配置整理到 "Inherit" 这个值就把它修好了。

我 运行 在本地 VM 上编译大型代码库。尝试增加页面文件大小等,但没有用。在我的案例中唯一有效的是在 Hyper-V VM 设置中禁用动态内存并为 VM 提供更多 RAM,8GB -> 16GB。

显然 VS 会预先分配它的内存,因此它只使用提供给 VM 的初始值,不会触发任何动态内存更改。

由于 PCH 和内存问题,我们的构建在 Jenkins CI 管道中失败。

我们的问题是 WinRM 对允许的 shell 内存有一个下限。

更新此并将其设置为无限制后,我们不会再遇到与构建相关的内存问题。

winrm.cmd set winrm/config/winrs @{MaxMemoryPerShellMB="0"}

一些背景: