memusage は収集したデータをテキスト形式で出力することもできるし、 memusagestat(1) を使って収集したデータをグラフにした PNG ファイルを作成することもできる (以下の -p オプションを参照)。
この概要行の直後には、 監視対象の各関数の呼び出し回数、 割り当て・割り当て解除された全メモリー量、 失敗した回数がテーブルで表示される。 realloc(3) と mremap(2) の場合には、 フィールド "nomove" でブロックアドレスを変更した再割り当て数を、 フィールド "dec" でブロックサイズが減少した再割り当て数が追加で表示される。 realloc(3) の場合、 フィールド "free" でブロックの解放が行われた再割り当て (サイズが 0 の再割り当て) の数も追加で表示される。
memusage が出力するテーブルの "realloc/total memory" (再割り当てメモリー/全メモリー) には、 realloc(3) を使ってメモリーブロックをその前よりも小さいサイズに再割り当てされた場合は含まれない。 このため、 ("free" 以外の) すべての「総メモリー」のセルは "free/total memory" セルよりも大きくなることがある。
$ 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
#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);
}