运算符 new 在大量物理内存可用时引发异常

Operator new throws an exception while a large amount of physical memory is available

本文关键字:异常 物理内存 new 运算符      更新时间:2023-10-16

在我的程序中,我使用运算符new来分配大约130兆字节和一个异常被抛出,但我发现任务管理器中有超过 800 兆字节可用。我希望知道在 中指示为可用的物理内存之间的关系任务管理器和我的程序可以使用的内存。

另一个原因是内存碎片。当我请求内存分配时,内存是需要连续。有没有办法知道这种连续的记忆是否存在?

物理内存<>虚拟内存。

如果您运行的是 32 位应用程序,则最多可以寻址 2 GB 的内存(在 32 位操作系统上)。 即使您的计算机有 32 GB 的物理内存,您仍然被限制为 2 GB。如果你的机器有最少的物理内存(还记得我们都有128 MB物理内存的日子吗?),或者你正在运行许多其他应用程序,那么大小可以小于2 GB(整个页面文件必须在所有应用程序之间分配)。

即使有 2 GB 的内存,如果没有 130MB 的连续块可用,分配 130MB 也可能失败。 自Windows Vista以来,DLL随机分布在地址空间上(查找:ASLR),这(根据我的经验)似乎会导致大量内存碎片。

有几种解决方案可以解决您的问题:

  • 如果您可以控制正在运行的系统,则可以为系统禁用 ASLR。 如果您销售的是商业软件,请不要这样做。 您的客户不会接受这一点。
  • 如果 32 位应用在 64 位系统上运行,请为应用程序指定/LARGEADDRESSAWARE 标志(请参阅链接器标志或 editbin 实用工具)。 使用此标志,应用程序应该能够寻址 4 GB,而不是 2 GB。 仅当您确定没有使用指针做"肮脏"的事情(例如,减去不相关的指针)时才这样做。
  • 分配较小的内存块而不是一个大块。 抽象出你需要一个大块的事实(例如,围绕这个大块编写一个类)。

如果可能的话,我会选择最后一种选择。

我假设你在Windows上。可用的 RAM 量与 new 是否可以分配内存无关。这取决于进程的虚拟内存中是否有 130 MB 的连续虚拟内存块可用。将 RAM 视为一个有限的暂存器,操作系统可以从中非常快速地写入和读取。但是,如果它正在寻找的任何东西在临时中不可用,它将转到磁盘并将其写入暂存器。