Linux memory management overhead
c++, linux, memory
Solution
Memory allocation in C like languages must return memory suitably aligned [0] for all primitive types. This means memory allocation will usually give you at least 8 byte aligned memory so you can store `doubles` in them.
So when you request 1 byte of memory you will use at least 8 bytes due to the alignment requirement. On 64 bit systems memory allocation often gives you 16 byte aligned memory as these systems often have 16 byte large types (SSE vectors)
Additionally the memory allocator needs some space for its management data, like the size of the allocation. Depending on the implementation this data can be placed before or after the user allocated block of memory.
[0] Memory is aligned when the address/pointer is a multiple of the size it is accessed in, some cpus do not support unaligned access (e.g. sparc), others (like x86) can have performance penalties if you do so.
Problem
I was trying to explain the memory that has been taken to my application in Linux. I did a basic test and figured out that if we new some memory, it allocated at least 32 bytes for a single new. This is my code. ``` #include <iostream> #include <stdlib.h> using namespace std; int main(int argc, const char** argv) { int iBlockSize = atoi(argv[1]); int iBlockCount = atoi(argv[2]); for (int i = 0 ; i < iBlockCount ; i++) { cout << (int*)(new char[iBlockSize]) << endl; } return 0; }; ``` When I execute the `./a.out 8 100` it gave following result. ``` .... .... .... 0xf6db10 0xf6db30 0xf6db50 0xf6db70 0xf6db90 0xf6dbb0 0xf6dbd0 0xf6dbf0 0xf6dc10 0xf6dc30 0xf6dc50 0xf6dc70 ``` All the memory I got was having 32 bytes gap. Till 24 (BlockSize) it was the same. If it goes beyond 24 it is 48 bytes. ./a.out 25 100 ``` .... .... .... 0x18b30c0 0x18b30f0 0x18b3120 0x18b3150 0x18b3180 0x18b31b0 0x18b31e0 0x18b3210 0x18b3240 0x18b3270 0x18b32a0 ``` When I was testing this for larger sizes; figured out that the memory we are getting is increased by 16 bytes chunks keeping at least 8 byte overhead. My questions are, - Is my test correct? - Is it the correct behaviour of linux memory management? - If we new 8 bytes, we get 32. What happened to other 24? Reused or fragmenting overhead?