boehm gcを触ってみた
2016-11-22
TechLLVMでRubyっぽい感じの自作言語作ってるんだけど、なんかもうメモリ確保とGCのこと考えないといけないっぽい。早いなぁ(進捗がじゃなくて、オブジェクトを生成するという操作を考えた瞬間にメモリ確保が必要になるということ)
— yhara (Yutaka HARA) (@yhara) 2016年11月19日
ということでいろいろ考えたのだけど、とりあえずboehm gcをちょっと触ってみることにした。
Boehm GC
Macだとbrew install boehmgcで入る。
とりあえず最小のサンプル。GC_MALLOCというのがBoehm GC版のmallocで、メモリ確保にはこれを使うことになる。GCを開始するというAPIを呼んでいないけど、GC_MALLOC時に適宜呼ばれるようだ。
#include <gc.h>
int main(){
GC_INIT();
GC_MALLOC(100);
return 0;
}
gc1.cという名前で保存したとして、以下のように動かす。
$ cc -I/usr/local/Cellar/bdw-gc/7.6.0/include/ \
-L/usr/local/Cellar/bdw-gc/7.6.0/lib/ -lgc -g -o gc1 \
gc1.c
$ ./gc1
巷のサンプルだとGC_INITを呼んでいない例もあるが、環境によっては呼ぶ必要がある。実際今回はこれを呼ばないとGC_MALLOCの引数が小さいときにSEGVするという結果になった(1000とか10000だと大丈夫)。
環境変数
https://github.com/ivmai/bdwgc/blob/master/doc/README.environment に解説があるが、Boehm GCを利用したプログラムに環境変数を与えることでGCの挙動を制御できる。例えばGC_PRINT_STATSをオンにすると、先ほどの何もしないプログラムでも以下のような出力が出る。
$ GC_PRINT_STATS=1 ./gc1
Grow heap to 64 KiB after 0 bytes allocated
Number of processors = 4
Started 3 mark helper threads
Initiating full world-stop collection!
--> Marking for collection #1 after 0 allocated bytes
GC #1 freed 0 bytes, heap 64 KiB
World-stopped marking took 0 msecs (0 in average)
In-use heap: 0% (0 KiB pointers + 0 KiB other)
0 finalization entries; 0/0 short/long disappearing links alive
0 finalization-ready objects; 0/0 short/long links cleared
Finalize plus initiate sweep took 0 + 0 msecs
Complete collection took 0 msecs
Adding block map for size of 7 granules (112 bytes)
とりあえず今日はここまで。次は、これとLLVMを組み合わせてみる。