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の関数を使うようにすれば、メモリ使用量は増えません。

objc
[RAW]
  1. #include <objc/Object.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #ifdef USE_GC
  5. #include <objc/objc-api.h>
  6. #include <gc/gc.h>
  7. static void* my_gc_calloc(size_t n, size_t s) {
  8. void* p = GC_malloc(n * s);
  9. memset(p, 0, n * s);
  10. return p;
  11. }
  12. static void __attribute__ ((constructor))
  13. init_alloc_() {
  14. printf("use gc.\n");
  15. _objc_malloc = GC_malloc;
  16. _objc_atomic_malloc = GC_malloc_atomic;
  17. _objc_valloc = GC_malloc;
  18. _objc_realloc = GC_realloc;
  19. _objc_calloc = my_gc_calloc;
  20. _objc_free = GC_free;
  21. }
  22. // int use_gc = init_alloc_();
  23. #endif // USE_GC
  24. int main() {
  25. while (1) {
  26. int i;
  27. for (i = 0; i < 10000; i++) [Object alloc];
  28. sleep(1);
  29. }
  30. return 0;
  31. }

サイト内関連文書

Boehm GC を使う
C/C++の場合。