3

I know that if a process does a malloc() but doesn't actually write on this memory, Linux consider that this memory is free and can be used by other processes (overcommit).

Anyway, is there a way to know how much memory was malloc()ed by a given process? (even if not used)

This info exists on a system wide basis in /proc/meminfo, but I'd like to know for a specific process.

I dug in /proc/<PID>/{smaps,stat,statm} but I'm unsure that it displays this information.

  • Since you're running on Linux, malloc_info() might also be of interest: man7.org/linux/man-pages/man3/malloc_info.3.html It doesn't really answer the question as it's only run from within a process, but if you do have control over the source code for your process(es) of interest, you might be able to make use of it. There are also some hacks you can do with LD_PRELOAD to load a custom shared object into the address space when the process(es) start that could emit the information you need upon receipt of a signal, for example. That might be a bit risky, though. – Andrew Henle Apr 7 '17 at 13:46
  • 1
    @Andrew you could also run the process in a debugger and call the function from the debugger... – Stephen Kitt Apr 9 '17 at 13:20
4

Calls to malloc() which cause the data segment size to change (i.e., that don’t re-use previously allocated memory — so allocations which result in calls to sbrk() or mmap()) show up in /proc/$PID/statm and /proc/$PID/stat.

In statm, the first field shows the total program size, and the sixth field shows the number of pages of data; both of these reflect memory allocations (even when unused).

In stat, the field to look at is vsize (the 23rd field currently).

(See tables 1-3 and 1-4 in the proc documentation.)

Note that these show total memory use and total data segment sizes, so you can’t distinguish between memory that’s been malloc()ed and other memory usage.

You can see this in action with the following program:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) {
  void *buf;
  puts("Waiting before allocating...");
  sleep(20);
  buf = malloc(10*1024*1024*1024L);
  puts("Sleeping after allocating...");
  sleep(20);
  free(buf);
  return 0;
}

(Excellent error handling as always.) Then

$ ./356532&
[1] 4239
Waiting before allocating...
$ cat /proc/4239/statm
1043 172 154 1 0 81 0
$ cat /proc/4239/stat | awk '{print $23}'
4272128
Sleeping after allocating...
$ cat /proc/4239/statm
2622484 172 154 1 0 2621522 0
$ cat /proc/4239/stat | awk '{print $23}'
10741694464

Andrew Henle pointed out malloc_info(3), and you can actually use that on pretty much any process. Using the example program above, without any debugging info (just to show that it’s not necessary):

$ gdb ./356532
> break free

(this sets up a breakpoint at the call to free in the program — actually any call to free, but we’ll hit “ours” first; trying this with malloc won’t be as useful because the startup code uses malloc)

> run

When gdb hits a breakpoint, you can call malloc_info like this:

> call malloc_info(0, stdout)

This will dump the malloc information.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.