heapstat: C-heap の利用状況確認

heapstat コマンドとは?

heapstat コマンドは動作中のプロセスや core ファイルから、アプリケーションの C-heap 領域の利用状況を表示するコマンドです。

アプリケーションが malloc(3C) を使ってメモリを確保した場合アプリの必要に応じて C-heap 領域が拡張します。しかしながら、free(3C)を呼び出しても実際にはこのメモリブロックはシステムに返却されません。フリーされたメモリブロックはフリーリストの置かれ、その後のアプリからの確保要求のために保持されます。

このコマンドは C-heap 内の空きメモリサイズを表示するツールになります。

使い方

heapstat [-v] { pid | core } [interval]

プロセスID(PID)を引数に与えることで heapstat コマンドは動作中のプロセスの C-heap 領域の利用状況を表示します。

$ heapstat 14641    
   free tree    next free   small free  bottom size    heap size    free size   free%
    size(kb)     size(kb)     size(kb)         (kd)         (kb)         (kb)     (%)
          16            0           17            3         6656           36       0 

もし引数としてインターバルも指定した場合、heapstat コマンドは指定した間隔(秒)毎に利用状況を出力します。

$ heapstat 14680 2
   free tree    next free   small free  bottom size    heap size    free size   free%
    size(kb)     size(kb)     size(kb)         (kd)         (kb)         (kb)     (%)
         327            0           67            0         8192          395       4 
         327            0           67            0         8192          395       4 
         327            0           66          227         8192          621       7 
         327            0           66          227         8192          621       7 
         327            0           66          227         8192          621       7 
         327            0           66          227         8192          621       7 

もし PID の代わりに core ファイルのファイル名を指定した場合は core ファイルに含まれる C-heap 領域の使用状況を出力します。

$ heapstat /var/tmp/core.974                                                                   
   free tree    next free   small free  bottom size    heap size    free size   free%
    size(kb)     size(kb)     size(kb)         (kd)         (kb)         (kb)     (%)
           0            1        51199        52851       129856       104051      80 

出力項目

free tree size

Solarismalloc は Self-Adjusting Binary Search Trees を使ってフリーされたメモリブロックを管理しています。
この列はこのバイナリツリー配下のフリーサイズの合計値を報告します。

next free size

free(3C)が呼ばれたタイミングではフリーされたブロックはフリーリストには追加されません。それらは「Last Freed」といフラグがつけられ、次回の malloc(3C)呼び出しまで保持されます。もし次回の malloc(3C) での要求サイズがこの保持したブロックのサイズに合致するなら、それがそのままアプリに返却されますが、もし要求に合わない場合にはフリーリストに追加されます。
この列は最後にフリーされ保持されているメモリブロックのサイズを表示します。

small free size

もし malloc(3C) が 64バイト以下のサイズのメモリを要求された場合、malloc(3C) は小さなサイズで C-heap を拡張する事無く、連続した小さなブロックを一度に確保し、後でリクエストされるまで保持します。(128個)
この列はこの未仕様の小さなブロックの合計サイズを表示します。

bottom size

この列はC-heap領域のの最後のフリーな塊のサイズを表示します。

heap size

この列は現在のアプリケーションのC-heap領域のサイズを表示します。

free size

この列はC-heap 領域内の空きサイズを表示します。

= free tree size + next free size + small free size + bottom size

free%

この列はC-heap領域内のの空きサイズの比率を表示します。

ダウンロード

以下のリンクからソースコードのアーカイブをダウンロードできます。
heapstat-master.zip

またコードは github で参照することもできます。

https://github.com/kaizawa/heapstat

コンパイル方法

./configure、make にてコンパイルします。
インストールする際には root 権限のあるアカウントで make install を実行します。

$ ./configure                                                       
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for a BSD-compatible install... /usr/bin/ginstall -c
checking for isainfo... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating heapstat-test/Makefile
$ make
gcc -g -I. -lproc -DPACKAGE_NAME=\"heapstat\" -DPACKAGE_TARNAME=\"heapstat\" -DPACKAGE_VERSION=\"0.1.0\" -DPACKAGE_STRING=\"heapstat\ 0.1.0\" -DPACKAGE_BUGREPORT=\"admin2@whiteboard.ne.jp\" -DPACKAGE_URL=\"\" -W -Wall -Wno-unknown-pragmas -Iinc -m64 -o heapstat heapstat_main.c
gcc -g -I. -lproc -DPACKAGE_NAME=\"heapstat\" -DPACKAGE_TARNAME=\"heapstat\" -DPACKAGE_VERSION=\"0.1.0\" -DPACKAGE_STRING=\"heapstat\ 0.1.0\" -DPACKAGE_BUGREPORT=\"admin2@whiteboard.ne.jp\" -DPACKAGE_URL=\"\" -W -Wall -Wno-unknown-pragmas -Iinc -m32 -o heapstat32 heapstat.c
gcc -g -I. -lproc -DPACKAGE_NAME=\"heapstat\" -DPACKAGE_TARNAME=\"heapstat\" -DPACKAGE_VERSION=\"0.1.0\" -DPACKAGE_STRING=\"heapstat\ 0.1.0\" -DPACKAGE_BUGREPORT=\"admin2@whiteboard.ne.jp\" -DPACKAGE_URL=\"\" -W -Wall -Wno-unknown-pragmas -Iinc -m64 -o heapstat64 heapstat.c
$ sudo make install 
/usr/bin/ginstall -c -d -m 0755 -o root -g bin /usr/local/bin
/usr/bin/ginstall -c -m 0755 -o root -g bin heapstat /usr/local/bin
/usr/bin/ginstall -c -m 0755 -o root -g bin heapstat32 /usr/local/bin
/usr/bin/ginstall -c -m 0755 -o root -g bin heapstat64 /usr/local/bin

テストした Solaris バージョン

このコマンドは Illumos(OpenSolairs)の libc malloc(3C) のコードを元に書いています。
現在のところ Oracle Solaris 11.1 でも動作することは確認できていますが、今後 Solarismalloc(3C)の実装が変わった場合には、このコマンドが正しく動作しなくなる可能性があります。

License

This program is provided under CDDL License.