6

我需要用 new 分配大块内存。

我坚持使用 new 因为我正在为两部分应用程序的生产者端编写一个模拟。实际的生产者代码正在分配这些大块,我的代码有责任删除它们(在处理它们之后)。

有没有办法可以确保我的应用程序能够从堆中分配如此大量的内存?我可以将堆设置为更大的大小吗?

我的情况是 64 个 288000 字节的块。有时我要分配 12 个,而其他时候我要分配 27 个。我得到一个 std::bad_alloc 异常。

这是:C++,Linux 上的 GCC(32 位)。

4

5 回答 5

9

关于C++/GCC/Linux(32bit) 中的新功能...

已经有一段时间了,它依赖于实现,但我相信new会在幕后调用malloc()Malloc(),除非您要求超出进程地址空间或超出指定(ulimit/getrusage)限制的内容,否则不会失败。即使您的系统没有足够的 RAM+SWAP。例如: 我相信,在具有 256Meg RAM + 0 SWAP 的系统上malloc(1gig)会成功。

但是,当您使用该内存时,内核会通过延迟分配机制提供页面。那时,当您第一次读取或写入该内存时,如果内核无法为您的进程分配内存页面,它会杀死您的进程。

当您的同事的核心泄漏速度较慢时,这可能是共享计算机上的问题。特别是当他开始淘汰系统进程时。

因此,您看到 std::bad_alloc 异常的事实是“有趣的”。

现在new将在分配的内存上运行构造函数,在它返回之前接触所有这些内存页面。根据实现,它可能会捕获内存不足信号。

你用普通的 o'l malloc试过这个吗?

您是否尝试过运行“免费”程序?你有足够的可用内存吗?

正如其他人所建议的那样,您是否检查了limit/ulimit/getrusage()的硬约束和软约束?

你的代码到底是什么样的?我猜是新的 ClassFoo [ N ]。或者也许是new char [N]

什么是sizeof(ClassFoo)?什么是N

对于大多数现代机器来说,分配 64*288000 (17.58Meg) 应该是微不足道的……您是在嵌入式系统上运行还是在其他特殊的系统上运行?

或者,您是否与自定义分配器链接?你的班级有自己的分配器吗?

您的数据结构(类)是否分配其他对象作为其构造函数的一部分?

有人篡改了您的库吗?您是否安装了多个编译器?您是否使用了错误的包含或库路径?

您是否链接过时的目标文件?您是否只需要重新编译所有源文件?

你能创建一个简单的测试程序吗?仅仅几行代码就可以重现该错误?还是您的问题在其他地方,只出现在这里?

--

对于它的价值,我已经在 g++ 下的 32 位 linux 中分配了超过 2gig 的新数据块。你的问题在别处。

于 2009-02-26T16:59:18.373 回答
4

您可能受到进程 ulimit 的限制;运行ulimit -a并检查虚拟内存和数据段大小限制。除此之外,您能否发布您的分配代码,以便我们了解实际情况?

于 2009-02-26T12:44:38.203 回答
1

更新:

我已经修复了一个数组索引错误,现在它正在正确分配。

如果我不得不猜测......我在我的堆中走来走去并且正在搞乱malloc的数据结构。(??)

于 2009-02-26T20:18:52.527 回答
0

我建议在程序启动时分配所有内存并使用新位置来定位缓冲区。为什么要采用这种方法?好吧,您可以手动跟踪碎片等。没有可移植的方法来确定可以为您的进程分配多少内存。我很肯定有一个特定于 linux 的系统调用可以为您提供该信息(想不出它是什么)。祝你好运。

于 2009-02-26T16:23:50.657 回答
0

当您在不同时间运行程序时会出现不同的行为,这一事实让我认为分配代码不是真正的问题。相反,其他人正在使用内存,而您是金丝雀,发现它丢失了。

如果那个“其他人”在你的程序中,你应该可以使用Valgrind找到它。

如果其他人是另一个程序,您应该能够通过转到不同的运行级别来确定这一点(尽管您不一定知道罪魁祸首)。

于 2009-02-26T18:00:54.683 回答