c++ - 新运算符(以及 malloc)无法分配 ~ 450 MB 内存

标签 c++ qt memory malloc new-operator

<分区>

我正在开发一个程序,该程序在内存中存储大约 2.2 亿个短值的数组。这 block 数据是这样分配的:

short * arrayName = new short[SIZE_OF_ARRAY];

然后文件的内容被读入内存。在团队中的另一个人对程序的整体架构进行大规模更新后,这条确切的线开始使程序崩溃。消息是这样的:

Microsoft Visual C++ Runtime Library
Runtime Error!
abnormal program termination

它会在调用内存分配时立即发生(不会执行其他行,例如检查指针是否为 NULL)。即使在几天之后,我们也不清楚其他代码中究竟是什么更改导致此行开始以这种方式运行(实际上,甚至远程链接到此数组的任何内容都没有更改)。

在 Linux(确切地说是 Ubuntu)上,一切正常;此问题仅存在于 Windows 机器上。在 64 位 Windows 操作系统上,此解决方法有帮助(在 .pro 文件中):

QMAKE_LFLAGS_WINDOWS += /LARGEADDRESSAWARE

在 32 位上,它没有帮助。

通过以下方式用 malloc 替换该行让我检查它之后的指针是否为 NULL(确实如此)并从 errno 中获取错误代码,即 12 (ENOMEM) =“内存不足”。

short * arrayName = (short *)malloc(SIZE_OF_ARRAY * sizeof(short));

This StackOverflow question似乎是同一个问题;它的相似性甚至达到了分配更少量的内存有效(但 450 MB 无效)的程度。那里的答案表明存在高内存碎片,并且 new/malloc 无法分配连续的内存区域,但就我而言,问题在重启后仍然存在,当时只有 2 个物理 GB(和 4 个虚拟 GB)中的 600 MB使用过,所以它在某种程度上被排除在外(另外,就像我提到的,完全相同的代码行之前已经工作过)。

我主要怀疑它与堆大小有关(尽管我不确定 new 和 malloc 是否都将内存分配给堆;而且我还没有找到在 Qt 中更改堆大小的方法) .我在这里遗漏了什么吗?

最佳答案

由于地址空间不足而不是 RAM 不足,内存分配失败。缺少 RAM 会导致程序变慢,并在程序被分页到磁盘时出现大量磁盘抖动。

/LARGEADDRESSAWARE 告诉操作系统您的应用可以接受更大的地址空间。 Win64 将为 Win32 应用程序提供 3GB 地址空间,这在 Win32 上不是标准的。

关闭 ASLR 会有所帮助,因为它将以线性方式加载 DLL(因此以可预测的偏移量加载,这是一种安全风险)。使用 ASLR,DLL 分散在内存中。只有 10 个 DLL 分散在 2 GB 的地址空间中(这低得不切实际),它们之间的平均空间约为 200 MB。

关于c++ - 新运算符(以及 malloc)无法分配 ~ 450 MB 内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18178367/

相关文章:

c++ - QNetworkAccessManager 即使在另一个线程中也会卡住 GUI

windows - 在 Windows 上重命名 DLL

c++ - 在 Visual Studio C++ 2008 中链接库 (.lib) 和 (.dll)

c++ - Qt:将 QGraphicsView 调整为窗口大小

c++ - 为什么会这样编译?期待 "cannot assign a constant to a non-const reference"

c++ - 从 ARM 的源代码交叉编译 Qt 4.7 的问题

C++ 需要线程安全的经过良好测试的容器(非微软)

javascript - Javascript 中依赖于其范围之外的变量的函数会导致内存泄漏吗?

c - Windows 共享内存中的奇怪错误

c - 在windows下查找程序在c中使用的总内存