How to find out how much memory is actually used when calling malloc?

If I call:

char *myChar = (char *)malloc(sizeof(char)); 

I will most likely use more than 1 byte of memory, because malloc will most likely use some memory on its own to track free blocks on the heap, and this may cost me some memory, always aligning the allocation along certain boundaries.

My question is : is there a way to find out how much memory is actually being used by a particular malloc call, including the effective alignment cost and the overhead used by malloc / free ?

To be clear, I do not ask you to find out how much memory the pointer indicates after calling malloc . Rather, I am debugging a program that uses a lot of memory, and I want to know which parts of the code allocate how much memory. I would like to be able to account for internal memory, which very closely matches the numbers indicated above. Ideally, I would like to do this programmatically based on "per-t21> -call", as opposed to getting a summary at a breakpoint.

+4
source share
4 answers

There is no portable solution for this, however, for the environment in which you are interested, there may be specific solutions for the operating system.

For example, with glibc on Linux, you can use the mallinfo() function from <malloc.h> , which returns a struct mallinfo . The uordblks and hblkhd this structure contain the dynamically allocated address space used by the program, including auxiliary service data - if you understand the difference in this before and after each call to malloc() , you will know the amount of space used by this call. (The overhead is not necessarily constant for every call to malloc() ).

Using your example:

 char *myChar; size_t s = sizeof(char); struct mallinfo before, after; int mused; before = mallinfo(); myChar = malloc(s); after = mallinfo(); mused = (after.uordblks - before.uordblks) + (after.hblkhd - before.hblkhd); printf("Requested size %zu, used space %d, overhead %zu\n", s, mused, mused - s); 

Indeed, the overhead is likely to be quite negligible unless you make a very large number of very small distributions, which is bad anyway.

+8
source

It really depends on the implementation. You really have to use a memory debugger. On Linux, the Valgrind Massif tool can be useful. There are libraries for debugging memory such as dmalloc, ...

However, typical overheads:

  • 1 int for storing flags of size + of this block.
  • maybe 1 int to hold the size of the previous / next block to help block blocking.
  • There are 2 pointers, but they can only be used in free() 'd blocks, which are reused to store applications in dedicated blocks.
  • Alignment according to the corresponding type, for example: double .
  • -1 int (yes, this is minus) of the next / previous chunk field containing our size if we are a selected block, since we cannot be crushed until we free ourselves.

Thus, the minimum size can be from 16 to 24 bytes. and the minimum overhead can be 4 bytes.

But you can also satisfy every allocation across memory pages (usually 4Kb), which means that the overhead for smaller allocations will be huge. I think OpenBSD does this.

+2
source

There is nothing in the C library to query the total amount of physical memory used by the malloc() call. The amount of allocated memory is controlled by the fact that any memory manager is connected behind the scenes, which includes malloc() . This memory manager can allocate as much additional memory as it sees fit for its internal tracking purposes, in addition to the additional memory that the OS itself requires. When you call free() , it calls the memory manager, which knows how to access this extra memory so that everything is correctly released, but you cannot find out how much memory is associated with it. If you need this little thing, you need to write your own memory manager.

0
source

If you use valgrind / Massif, it is possible to show either the malloc value or the top value, which are different LOT in my experience. Here is an excerpt from the Valgrind manual http://valgrind.org/docs/manual/ms-manual.html :

... However, if you want to measure all the memory used by your program, you can use -pages-as-heap = yes. When this option is enabled, Profiling for a normal Massif array array is replaced with a lower-level profiling page. Each page allocated through mmap and similar system calls is treated as a separate block. This means that code, data, and BSS segments are measured because they are only memory pages. Even the stack is measured ...

0
source

Source: https://habr.com/ru/post/1384021/


All Articles