new[] doesn't decrease available memory until populated

狂风中的少年 提交于 2021-02-08 12:24:09

问题


This is in C++ on CentOS 64bit using G++ 4.1.2.

We're writing a test application to load up the memory usage on a system by n Gigabytes. The idea being that the overall system load gets monitored through SNMP etc. So this is just a way of exercising the monitoring.

What we've seen however is that simply doing:

char* p = new char[1000000000];

doesn't affect the memory used as shown in either top or free -m

The memory allocation only seems to become "real" once the memory is written to:

memcpy(p, 'a', 1000000000);   //shows an increase in mem usage of 1GB

But we have to write to all of the memory, simply writing to the first element does not show an increase in the used memory:

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

Is this normal, has the memory actually been allocated fully? I'm not sure if it's the tools we are using (top and free -m) that are displaying incorrect values or whether there is something clever going on in the compiler or in the runtime and/or kernel.

This behavior is seen even in a debug build with optimizations turned off.

It was my understanding that a new[] allocated the memory immediately. Does the C++ runtime delay this actual allocation until later on when it is accessed. In that case can an out of memory exception be deferred until well after the actual allocation of the memory until the memory is accessed?

As it is it is not a problem for us, but it would be nice to know why this is occurring the way it is!

Cheers!

Edit:

I don't want to know about how we should be using Vectors, this isn't OO / C++ / the current way of doing things etc etc. I just want to know why this is happening the way it is, rather than have suggestions for alternative ways of trying it.


回答1:


Please look up for overcommit. Linux by default doesn't reserve memory until it is accessed. And if you end up by needing more memory than available, you don't get an error but a random process is killed. You can control this behavior with /proc/sys/vm/*.

IMO, overcommit should be a per process setting, not a global one. And the default should be no overcommit.




回答2:


When your library allocates memory from the OS, the OS will just reserve an address range in the process's virtual address space. There's no reason for the OS to actually provide this memory until you use it - as you demonstrated.

If you look at e.g. /proc/self/maps you'll see the address range. If you look at top's memory use you won't see it - you're not using it yet.




回答3:


About the second half of your question:

The language standard doesn't allow any delays in throwing a bad_alloc. That must happen as an alternative to new[] returning a pointer. It cannot happen later!

Some OSs might try to overcommit memory allocations, and fail later. That is not conforming to the C++ language standard.



来源:https://stackoverflow.com/questions/5341395/new-doesnt-decrease-available-memory-until-populated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!