Objective-Cでガベージコレクション
(2008.9.14) ページを分割し、最新の版に更新。
Mac OS XのObjective-Cは、Leopard (Mac OS X 10.5) からガベージコレクションが有効になりました。
しかし、Linuxのgccでは今のところ (gcc 4.3.0)、標準ではガベージコレクションが使用されないようです。
ここでは、Linuxのgccでガベージコレクションを使う方法を紹介します。
準備
ガベージコレクションのライブラリは、Boehm GCがメジャーです。
2008.9現在の最新版はバージョン7.1 (2008.5リリース) です。
自分でコンパイルしてもいいですが、Fedora 9 Linux にはバージョン7.0がパッケージ化されていますので、今回はこれを使ってみます。yumコマンドでインストールします。
# yum install gc-devel
フックを書き換える
Objective-CでGCを使うには、メモリ関係のフックを書き換えます。
ヘッダ <objc/objc-api.h> で宣言されている_objc_malloc などをそれぞれ設定すれば、オブジェクトの生成などのときにその関数が使われます。
次のサンプルはBoehm GCの関数を設定しています。calloc だけBoehm GCに関数がないので、作りました。
GCなしはこのようにコンパイルします。
$ gcc -Wall objc-gc.m -lobjc
GCありはこう。
$ gcc -Wall -DUSE_GC objc-gc.m -lobjc -lgc
GCなしの場合はメモリが単調に増加しますか、init_alloc_()を呼ぶようにしてBoehm GCの関数を使うようにすれば、メモリ使用量は増えません。
- #include <objc/Object.h>
- #include <unistd.h>
- #include <stdio.h>
- #ifdef USE_GC
- #include <objc/objc-api.h>
- #include <gc/gc.h>
- static void* my_gc_calloc(size_t n, size_t s) {
- void* p = GC_malloc(n * s);
- memset(p, 0, n * s);
- return p;
- }
- static void __attribute__ ((constructor))
- init_alloc_() {
- printf("use gc.\n");
- _objc_malloc = GC_malloc;
- _objc_atomic_malloc = GC_malloc_atomic;
- _objc_valloc = GC_malloc;
- _objc_realloc = GC_realloc;
- _objc_calloc = my_gc_calloc;
- _objc_free = GC_free;
- }
- // int use_gc = init_alloc_();
- #endif // USE_GC
- int main() {
- while (1) {
- int i;
- for (i = 0; i < 10000; i++) [Object alloc];
- sleep(1);
- }
- return 0;
- }
サイト内関連文書
- Boehm GC を使う
- C/C++の場合。