使用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 ++ /当前的做事方式等等。我只想知道为什么会发生这种情况,而不是而不是有其他尝试方式的建议。
答案 0 :(得分:17)
当您的磁带库从操作系统分配内存时,操作系统将只保留进程虚拟地址空间中的地址范围。操作系统没有理由在您使用它之前实际提供此内存 - 如您所示。
如果你看一下,例如/proc/self/maps
您会看到地址范围。如果您查看top的内存使用,您将看不到它 - 您还没有使用它。
答案 1 :(得分:8)
请注意过度使用。默认情况下,Linux在访问之前不会保留内存。如果最终需要的内存超过可用内存,则不会出现错误,但会导致随机进程被终止。您可以使用/proc/sys/vm/*
控制此行为。
IMO,overcommit应该是每个进程设置,而不是全局设置。默认情况下不应该过度使用。
答案 2 :(得分:2)
关于问题的后半部分:
语言标准不允许任何延迟抛出bad_alloc。这必须作为new []返回指针的替代方案发生。以后不可能发生!
某些操作系统可能会尝试过度使用内存分配,稍后会失败。这不符合C ++语言标准。