运算符 new 在大量物理内存可用时引发异常
Operator new throws an exception while a large amount of physical memory is available
在我的程序中,我使用运算符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 视为一个有限的暂存器,操作系统可以从中非常快速地写入和读取。但是,如果它正在寻找的任何东西在临时中不可用,它将转到磁盘并将其写入暂存器。
相关文章:
- 从构造函数抛出异常时如何克服内存泄漏
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 如何在 WSL 2 中读取物理内存?
- 我们应该在抛出异常之前取消分配内存吗
- 未找到匹配的运算符删除;如果初始化引发异常,内存将不会被释放
- 静态局部变量没有物理内存
- Linux如何知道过程使用了多少物理内存
- 未处理的异常:_com_error内存位置 0x0040f4ac
- 使用C++异常的内存泄漏
- 评估 C/C++ 内存泄漏时的虚拟与物理内存
- 运算符 new 在大量物理内存可用时引发异常
- std::矢量元素在物理内存中是否连续
- 关于c++指针和物理内存
- 如何在Windows上直接从物理内存中读取
- 虚拟内存或物理内存
- 用异常避免内存泄漏
- 不断增加物理内存Visual c++ CryptMsgClose和CryptReleaseContext
- 如何获得windows中特定进程使用的物理内存和cpu
- WMI给我不完整的硬件信息(物理内存)
- 限制每个进程的物理内存