memusage(1)
๐ memusage โ from the memusage(1) page, General Commands Manual energy ๐
okay bestie, sit DOWN, because this little script is about to tell you exactly how much memory your program is gulping ๐
โจ NAME โจ
memusage โ profile memory usage of a program ๐
๐ธ SYNOPSIS ๐ธ
memusage [option ...] program [programoption ...]
๐ฆ DESCRIPTION ๐ฆ
So like. memusage is a bash(1) script, right? and its whole thing is profiling the memory usage of the program program. the way it does this is SO clever โ it preloads the libmemusage.so library into the caller's environment (through the LD_PRELOAD environment variable, peep ld.so(8) for the deets). ๐
then libmemusage.so traces memory allocation by intercepting calls to malloc(3), calloc(3), free(3), and realloc(3). and if you want more? optionally it can also intercept calls to mmap(2), mremap(2), and munmap(2). obsessed.
memusage can spit the collected data out as plain text, OR it can hand things off to memusagestat(1) (that's the -p option, scroll down bestie) to make a PNG file with a whole graphical representation of all that collected data. main character behaviour, honestly. โจ
๐ Memory usage summary ๐
the "Memory usage summary" line that memusage outputs has three fields, and yes you need to know all three:
- heap total โ the sum of
sizearguments of allmalloc(3)calls, plus the products of arguments (n*size) of allcalloc(3)calls, plus the sum oflengtharguments of allmmap(2)calls. and forrealloc(3)andmremap(2)? if the new size of an allocation is bigger than the previous size, then the sum of all those differences (new size minus old size) gets added in. math is mathing. ๐งฎ - heap peak โ the maximum of all
sizearguments ofmalloc(3), all products ofn*sizeofcalloc(3), allsizearguments ofrealloc(3),lengtharguments ofmmap(2), andnew_sizearguments ofmremap(2). - stack peak โ before the first call to any monitored function, the stack pointer address (that's the base stack pointer) gets saved. after each function call, the actual stack pointer address is read and the difference from the base stack pointer is computed. the maximum of all those differences? that's your stack peak. ๐
and IMMEDIATELY after that summary line, there's a table showing the number calls, total memory allocated or deallocated, and number of failed calls for each intercepted function. for realloc(3) and mremap(2) there's an extra field "nomove" which shows reallocations that changed the address of a block, plus an extra "dec" field showing reallocations that decreased the size of the block. and for realloc(3), there's one more extra field "free" that shows reallocations which caused a block to be freed (like, the reallocated size was 0). ๐ซถ
โ ๏ธ heads up bestie, this part matters: the "realloc/total memory" of the table thatmemusageoutputs does not reflect cases whererealloc(3)is used to reallocate a block of memory to have a smaller size than previously. this can make the sum of all "total memory" cells (excluding "free") come out larger than the "free/total memory" cell. it's giving math that doesn't add up and that's just how it is, no cap. ๐
๐ง Histogram for block sizes ๐ง
the "Histogram for block sizes" gives you a breakdown of memory allocations into various bucket sizes. little buckets, filling up with your memory. adorable. ๐ธ
๐ OPTIONS ๐
-nname,--progname=name โ name of the program file to profile.-pfile,--png=file โ generate a PNG graphic and store it in file.-dfile,--data=file โ generate a binary data file and store it in file.-u,--unbufferedโ do not buffer output.-bsize,--buffer=size โ collect size entries before writing them out.--no-timerโ disable timer-based (SIGPROF) sampling of the stack pointer value.-m,--mmapโ also tracemmap(2),mremap(2), andmunmap(2).-?,--helpโ print help and exit.--usageโ print a short usage message and exit.-V,--versionโ print version information and exit.
and these next ones? they only apply when you're generating graphical output, iykyk: ๐จ
-t,--time-basedโ use time (rather than number of function calls) as the scale for the X axis.-T,--totalโ also draw a graph of total memory use.--title=name โ use name as the title of the graph.-xsize,--x-size=size โ make the graph size pixels wide.-ysize,--y-size=size โ make the graph size pixels high.
๐ฅ EXIT STATUS ๐ฅ
the exit status of memusage is equal to the exit status of the profiled program. simple as that, periodt.
๐ญ BUGS ๐ญ
to report bugs, see http://www.gnu.org/software/libc/bugs.html
(not me telling you where to file the bug reports, go off ๐ซถ)
โญ EXAMPLES โญ
below is a simple program that reallocates a block of memory in cycles that rise to a peak before then cyclically reallocating the memory in smaller blocks that return to zero. after compiling the program and running the following commands, a graph of the memory usage of the program can be found in the file memusage.png:
$ memusage --data=memusage.dat ./a.out;
...
Memory usage summary: heap total: 45200, heap peak: 6440, stack peak: 224
total calls total memory failed calls
malloc| 1 400 0
realloc| 40 44800 0 (nomove:40, dec:19, free:0)
calloc| 0 0 0
free| 1 440
Histogram for block sizes:
192-207 1 2% ================
...
2192-2207 1 2% ================
2240-2255 2 4% =================================
2832-2847 2 4% =================================
3440-3455 2 4% =================================
4032-4047 2 4% =================================
4640-4655 2 4% =================================
5232-5247 2 4% =================================
5840-5855 2 4% =================================
6432-6447 1 2% ================
$ memusagestat memusage.dat memusage.png;
๐ Program source ๐
#include <stdio.h>
#include <stdlib.h>
#define CYCLES 20
int
main(int argc, char *argv[])
{
int i, j;
size_t size;
int *p;
size = sizeof(*p) * 100;
printf("malloc: %zu\n", size);
p = malloc(size);
for (i = 0; i < CYCLES; i++) {
if (i < CYCLES / 2)
j = i;
else
j--;
size = sizeof(*p) * (j * 50 + 110);
printf("realloc: %zu\n", size);
p = realloc(p, size);
size = sizeof(*p) * ((j + 1) * 150 + 110);
printf("realloc: %zu\n", size);
p = realloc(p, size);
}
free(p);
exit(EXIT_SUCCESS);
}
๐ SEE ALSO ๐
memusagestat(1), mtrace(1), ld.so(8)
and that's the whole thing bestie!! this page came from Linux man-pages 6.20, dated 2026-02-08 โ so you know it's fresh. go profile something, you absolute legend ๐โจ๐ฆ๐๐
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: GPL-2.0-or-later
- Copyright 2013, Peter Schiffer <pschiffe@redhat.com>
- Copyright 2014, Michael Kerrisk <mtk.manpages@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms