MEMUSAGE(1)

名前
memusage - プログラムのメモリー使用量のプロファイルを行う

書式
memusage [option]... program [programoption]...

説明
memusage は、 プログラム program のメモリー使用量のプロファイルを行う bash スクリプトである。 呼び出し元の環境に (LD_PRELOAD 環境変数を使って) libmemusage.so ライブラリをプレロードする。 ld.so(8) を参照。 libmemusage.so ライブラリは、 malloc(3), calloc(3), free(3), realloc(3) の呼び出しを横取りし、 メモリー割り当て状況の追跡を行う。 追加で、 mmap(2), mremap(2), munmap(2) を追跡することもできる。

memusage は収集したデータをテキスト形式で出力することもできるし、 memusagestat(1) を使って収集したデータをグラフにした PNG ファイルを作成することもできる (以下の -p オプションを参照)。

  メモリー使用量概要
memusage が出力する "Memory usage summary" (メモリー使用量概要) の行には以下のフィールドが含まれる。

    heap total
        malloc(3) のすべての呼び出しの size 引数の合計、 calloc(3) のすべての呼び出しの引数の積 (nmemb*size)、 mmap(2) のすべての呼び出しの length 引数の合計。 realloc(3) と mremap(2) の場合、 割り当ての新しいサイズが以前のサイズよりも大きい場合、 差分 (新しいサイズから古いサイズを引いた値) の合計が加算される。

    heap peak
        malloc(3) の size 引数、 calloc(3) の nmemb*size の積、 realloc(3) の size 引数、 mmap(2) の length 引数、 mremap(2) の new_size 引数、 の中の最大値。

    stack peak
        監視される関数の最初の呼び出しが行われる前に、 スタックポインターアドレス (ベーススタックポインター) が保存される。 関数のそれぞれの呼び出し後には、 実際のスタックポインターアドレスを読み込み、 ベースポインターアドレスを元に差分を計算する。これらの差分の最大値がスタックのピーク値となる。

この概要行の直後には、 監視対象の各関数の呼び出し回数、 割り当て・割り当て解除された全メモリー量、 失敗した回数がテーブルで表示される。 realloc(3) と mremap(2) の場合には、 フィールド "nomove" でブロックアドレスを変更した再割り当て数を、 フィールド "dec" でブロックサイズが減少した再割り当て数が追加で表示される。 realloc(3) の場合、 フィールド "free" でブロックの解放が行われた再割り当て (サイズが 0 の再割り当て) の数も追加で表示される。

memusage が出力するテーブルの "realloc/total memory" (再割り当てメモリー/全メモリー) には、 realloc(3) を使ってメモリーブロックをその前よりも小さいサイズに再割り当てされた場合は含まれない。 このため、 ("free" 以外の) すべての「総メモリー」のセルは "free/total memory" セルよりも大きくなることがある。

  ブロックサイズのヒストグラム
"Histogram for block sizes" (ブロックサイズのヒストグラム) は、 メモリー割り当てをバケットサイズ単位に分割した情報である。

オプション

-n name, --progname=name
    プロファイル対象のプログラムファイル名。

-p file, --png=file
    PNG 画像を生成し、 file に格納する。

-d file, --data=file
    バイナリーデータファイルを生成し、 file に格納する。

-u, --unbuffered
    出力バッファーリングを行わない。

-b size, --buffer=size
    出力する前に size 個のエントリーの収集を行う。

--no-timer
    スタックポインター値の時間ベースのサンプリング (SIGPROF) を無効にする。

-m, --mmap
    mmap(2), mremap(2), munmap(2) も追跡対象とする。

-?, --help
    ヘルプを表示し、終了する。

--usage
    簡潔な使用方法を表示して終了する。

-V, --version
    バージョン情報を表示して終了する。

以下のオプションは画像出力を行う場合にのみ適用される。

-t, --time-based
    X 軸の目盛として (関数呼び出し数ではなく) 時間を使用する。

-T, --total
    メモリーの全使用量のグラフも生成する。

--title=name
    グラフのタイトルとして name を使用する。

-x size, --x-size=size
    グラフの幅を size ピクセルにする。

-y size, --y-size=size
    グラフの高さを size ピクセルにする。

終了ステータス
終了ステータスはプロファイルしたプログラムの終了ステータスと同じになる。

バグ
バグ報告については http://www.gnu.org/software/libc/bugs.html を参照のこと。

例
以下の簡単なプログラムは、 ピークに達するまで繰り返しメモリーブロックの再割り当てを行い、 その後ブロックサイズが 0 になるまで繰り返し順に小さなブロックに再割り当てを行う。 このプログラムをコンパイルして以下のコマンドを実行すると、 このプログラムのメモリー使用量がファイル 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

  プログラムのソース
    #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);
    }

関連項目
memusagestat(1), mtrace(1), ld.so(8)

この文書について
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。