I have a c++ program that uses several very large arrays of doubles, and I want to reduce the memory footprint of this particular part of the program. Currently, I’m allocating 100 of them and they can be 100 Mb each.
Now, I do have the advantage, that eventually parts of these arrays become obsolete during later parts of the program’s execution, and there is little need to ever have the whole of any one of then in memory at any one time.
My question is this:
Is there any way of telling the OS after I have created the array with new or malloc that a part of it is unnecessary any more ?
I’m coming to the conclusion that the only way to achieve this is going to be to declare an array of pointers, each of which may point to a chunk say 1Mb of the desired array, so that old chunks that are not needed any more can be reused for new bits of the array. This seems to me like writing a custom memory manager which does seem like a bit of a sledgehammer, that’s going to create a bit of a performance hit as well
I can’t move the data in the array because it is going to cause too many thread contention issues. the arrays may be accessed by any one of a large number of threads at any time, though only one thread ever writes to any given array.
It depends on the operating system. POSIX – including Linux – has the system call
madviseto do improve memory performance. From the man page:See the man page of
madvisefor more information.Edit: Apparently, the above description was not clear enough. So, here are some more details, and some of them are specific to Linux.
You can use
mmapto allocate a block of memory (directly from the OS instead of the libc), that is not backed by any file. For large chunks of memory,mallocis doing exactly the same thing. You have to usemunmapto release the memory – regardless of the usage ofmadvise:If you want to get rid of some parts of this chunk, you can use
madviseto tell the kernel to do so:The address range is still valid, but it is no longer backed – neither by physical RAM nor by storage. If you access the pages later, the kernel will allocate some new pages on the fly and re-initialize them to zero. Be aware, that the dontneed pages are also part of the virtual memory size of the process. It might be necessary to make some configuration changes to the virtual memory management, e.g. activating over-commit.