TCMallocでメモリ割り当てを高速化する

TCMallocを利用するには、コンパイル時にlibtcmalloc.soをリンクするように指定すればよい。libtcmalloc.soが/usr/local/lib/ディレクトリにある場合、gccによるコンパイルは以下のようになる。

コンパイル時にTCMallocのライブラリをリンクするように指定

$ gcc -L/usr/local/lib/ -ltcmalloc ソースファイル名

このようにするだけで、malloc関数などによるメモリの割り当てや開放にTCMallocが使われるようになる。ソースコードには一切変更を加える必要はない。

もし再コンパイルせずにすでにある実行ファイルやコマンドにTCMallocを適用したい場合には、実行時にLD_PRELOAC環境変数にlibtcmalloc.soへのパスを設定すればよい。例えばbashの場合には次のようにする。

実行時にTCMallocを使うように指定

$ LD_PRELOAD=/usr/local/lib/libtcmalloc.so コマンド

この方法の場合、再コンパイルを必要としないため様々な既存のアプリケーションを高速化できるというメリットがあるが、開発チームでは"必ずしも推奨する方法ではない"としている。

以下はmallocsample.cというプログラムの実行速度を、TCMallocを使った場合と使わない場合で比べた例である。mallocsample.cはmalloc関数とfree関数によるメモリの割り当てと開放を100万回繰り返すだけのシンプルなプログラムだ。結果を見ると、TCMalloc使用時の方が明らかに高速に動作していることがわかる。

TCMalloc使用時の実行速度

$ gcc -o normal mallocsample.c 
$ gcc -o with-tcmalloc -L/usr/local/lib/ -ltcmalloc mallocsample.c 
$ time ./normal 
real    0m3.113s
user    0m1.253s
sys     0m1.845s
$ time ./with-tcmalloc 
real    0m0.724s
user    0m0.699s
sys     0m0.022s
$ time LD_PRELOAD=/usr/local/lib/libtcmalloc.so ./normal 
real    0m0.781s
user    0m0.757s
sys     0m0.022s

さて、TCMallocには後述するヒープチェッカーとヒーププロファイラがデフォルトで含まれており、-ltcmallocを指定してコンパイルした場合にこれらのバイナリも自動的にリンクされる。もしこれらの機能を必要としない場合には、代わりに次のようにlibtcmalloc_minimal.soをリンクすれば実行ファイルのサイズを縮小できる可能性があるとのことだ。

libtcmalloc_minimal.soをリンクしてコンパイル

$ gcc -L/usr/local/lib/ -ltcmalloc_minimal ソースファイル名

もし日常的にTCMallocを使用したい場合には、シェルの設定ファイルなどでLD_PRELOAD環境変数を設定してしまうか、コマンド毎に以下のようにエイリアスを張っておくといいだろう。

アプリケーションがTCMallocを使用するようにエイリアスを張る

alias firefox="LD_PRELOAD=/usr/local/lib/libtcmalloc.so firefox"

その他、デーモンとして起動するプログラムに適用したい場合には、各デーモンの起動スクリプト内でLD_PRELOADを設定すればよい。