函数不会抛出bad_alloc异常

时间:2015-09-20 10:27:15

标签: c++ exception out-of-memory bad-alloc

我试图通过Stroustrup的C ++ PL4书进行练习。任务是:

  

使用引发new的{​​{1}}分配大量内存。报道如何   分配了大量内存,花了多少时间。这样做两次:   一次不写入分配的内存,一次写入每个内存   元件。

以下代码不会引发bad_alloc异常。执行程序后,我收到消息" Killed"在终端。

另外。以下代码在~4秒内退出。但是当我取消注释内存使用消息时

std::bad_alloc

程序将运行几分钟。经过一段时间后,它打印出已经分配了数TB的内存,但我在System Monitor应用程序中看不到太多变化。那是为什么?

我使用Linux和System Monitor应用程序来查看用法。

// ++i;
// std::cout << "Allocated " << i*80 << " MB so far\n";

1 个答案:

答案 0 :(得分:5)

在现代残酷的世界中,调用new(以及malloc()或甚至brk())并不一定会分配内存。它只是(通过一系列层)向OS发送请求,并且OS分配虚拟内存区域(四舍五入到系统内存页面)。因此,只有后续访问到给定内存才能执行实际分配。

此外,现代操作系统允许内存“过度使用”。有时(取决于操作系统及其设置)应用程序可以要求操作系统甚至可以在理论上分配更多的内存,包括所有交换区域等,所有内容都没有任何明显的问题。例如,查看at this page

这样做是因为在现实生活中所有应用程序实际上在中同时使用所有分配的内存的情况是不太可能的。更常见的是,99.99%的时间,应用程序只使用部分内存并且经常执行,因此操作系统有机会无缝地提供请求。

增加机会以实际导致内存分配错误,您可以访问刚刚分配的元素,但我再也不会将其称为逐字保修,只是“关于增加可能性”。

在最糟糕的情况下,当这样的OS实际上发现它无法分配足够的(虚拟)内存,因为太多的应用程序同时请求访问其分离的分配数据时,OS内存管理器启动一个称为“OOM杀手”的特殊过程,只是通过启发式(=随机:)来选择应用程序。

现在依赖bad_alloc是一个坏主意。有时您可以实际接收它(例如,当使用ulimit/setrlimit人为地限制您的应用时),但一般情况下,您的应用程序将在不保证任何内容的环境中运行。只是不要记忆,并为其余的祈祷:)。