new []在填充之前不会减少可用内存

时间:2011-03-17 15:40:04

标签: c++ linux memory-management new-operator memory-overcommitment

使用G ++ 4.1.2在CentOS 64bit上使用C ++。

我们正在编写一个测试应用程序来加载系统上的内存使用量为n千兆字节。这个想法是整个系统负载通过SNMP等进行监控。所以这只是一种实施监控的方式。

然而,我们所看到的只是:

char* p = new char[1000000000];

不会影响使用的内存,如top或free -m

所示

一旦内存写入:

,内存分配似乎只会变为“真实”
memcpy(p, 'a', 1000000000);   //shows an increase in mem usage of 1GB

但是我们必须写入所有内存,只需写入第一个元素就不会显示已用内存的增加:

p[0] = 'a';    //does not show an increase of 1GB.

这是正常的,内存实际上已经完全分配了吗?我不确定它是否是我们正在使用的工具(top和free -m)显示不正确的值,或者在编译器或运行时和/或内核中是否有一些聪明的事情。

即使在关闭优化的调试版本中也可以看到此行为。

我的理解是新的[]立即分配了内存。 C ++运行时是否会延迟此实际分配,直到稍后访问它为止。在这种情况下,是否可以推迟内存异常直到实际分配内存直到访问内存为止?

因为它对我们来说不是问题,但是知道为什么会发生这种情况会很好!

干杯!

编辑:

我不想知道我们应该如何使用Vectors,这不是OO / C ++ /当前的做事方式等等。我只想知道为什么会发生这种情况,而不是而不是有其他尝试方式的建议。

3 个答案:

答案 0 :(得分:17)

当您的磁带库从操作系统分配内存时,操作系统将只保留进程虚拟地址空间中的地址范围。操作系统没有理由在您使用它之前实际提供此内存 - 如您所示。

如果你看一下,例如/proc/self/maps您会看到地址范围。如果您查看top的内存使用,您将看不到它 - 您还没有使用它。

答案 1 :(得分:8)

请注意过度使用。默认情况下,Linux在访问之前不会保留内存。如果最终需要的内存超过可用内存,则不会出现错误,但会导致随机进程被终止。您可以使用/proc/sys/vm/*控制此行为。

IMO,overcommit应该是每个进程设置,而不是全局设置。默认情况下不应该过度使用。

答案 2 :(得分:2)

关于问题的后半部分:

语言标准不允许任何延迟抛出bad_alloc。这必须作为new []返回指针的替代方案发生。以后不可能发生!

某些操作系统可能会尝试过度使用内存分配,稍后会失败。这不符合C ++语言标准。