Boehm GC

12月17日月曜日、晴れ

こちらに書かれたサンプルソースをビルドしてみることにする。

#include "gc.h"
#include <assert.h>
#include <stdio.h>

int main()
{
 int i;

 GC_INIT();	/* Optional on Linux/X86; see below.  */
 for (i = 0; i < 10000000; ++i)
  {
    int **p = (int **) GC_MALLOC(sizeof(int *));
    int *q = (int *) GC_MALLOC_ATOMIC(sizeof(int));
    assert(*p == 0);
    *p = (int *) GC_REALLOC(q, 2 * sizeof(int));
    if (i % 100000 == 0)
      printf("Heap size = %d\n", GC_get_heap_size());
  }
 return 0;
}

ライブラリー(libgc)のビルド手順は以下に書かれている。

注意が必要なのはライブラリーのビルドにいくつか必要なツールがあるということ。(といっても、オープンソースの C コードをビルドするなら必要になるごく一般的なもの)

This will require that you have C and C++ toolchains, git, automake, autoconf, and libtool already installed.

例示されたインストラクションをちょっと変更して、ヘッダーファイルとライブラリーをホームディレクトリーにインストールする。(昔の癖で、システム権限を持っていなくても使えるようにしたい)
ざっとこんな感じ:

cd /tmp
git clone git://github.com/ivmai/libatomic_ops.git
git clone git://github.com/ivmai/bdwgc.git
ln -s  $PWD/libatomic_ops bdwgc/
cd bdwgc
autoreconf -vif
automake --add-missing
./configure --prefix=$HOME/local
make && make check && make install

先のサンプルコードを gc-sample.c として保存しているとして、あとはこうすればビルドできて……:

CFLAGS=-I$HOME/local/include LDFLAGS=-L$HOME/local/lib\
 make LDLIBS=-lgc gc-sample

こうやって実行する:

LD_LIBRARY_PATH=$HOME/local/lib ./gc-sample

実行結果は以下のようになる:

$ LD_LIBRARY_PATH=$HOME/local/lib ./gc-sample
Heap size = 65536
Heap size = 131072
Heap size = 131072
...
Heap size = 131072

一千万回繰り返すことの、
整数ポインターを格納するに足りるメモリーを確保し、
整数を格納できるメモリーを確保し、
これを整数ふたつ分格納できるサイズに拡張して結果を先に確保したポインター変数に割り当てる。

ポインターサイズが4バイト、整数もまた4バイト(これを二つ分に拡張するから8バイトになる)。ここにはメモリーの回収コードが書かれていないので、ループを一周するごとに12バイトずつ消費量は増える ……はずなんだけれど、初回表示で65,536バイト、二回目で131,072バイトと増加するけれど、以降このサイズを超えることはない。

整数ポインター変数pも、整数メモリーqも、グローバルな参照をもっていないため、いつでも回収可能な状態。よってヒープの初期割り当て(65,536バイト)を一度増加させた後は、不要な参照をゴリゴリ開放・回収しているのだろう。

この記事が気に入ったらサポートをしてみませんか?