【コラム】

ダイナミックObjective-C

97 ガベージコレクション (2) - 実体であるlibauto

    木下誠  [2007/12/21]

    Leopardの発売から1カ月半が経過した。Objective-C 2.0に深く切り込みたいものとしては、Mac OS X 10.5であるDarwin 9.0に搭載されているObjective-Cランタイムのソースコード公開を待ち望んでいるのだが、なかなかその気配は訪れない。

    ただ待っているだけでは仕方ないので、手持ちの材料だけでObjective-C 2.0を探っていくことにしよう。Appleから公開されているドキュメントと、Mac OS X 10.4であるDarwin 8.10で公開されているソースコードを参考にしていく。

    ガベージコレクタの実体とそのソースコード

    では、前回の続きでガベージコレクションを探っていこう。

    本連載としては、まずソースコードレベルから話を始めたかったのだが、前述のとおりLeopardではまだソースコードが公開されていない。

    だがよく考えると、ガベージコレクションの機能自体は、Tigerで実装されていることを思い出した。たとえば、TigerのXcodeでビルドの設定を調べると、「Objective-Cガベージコレクションを有効にする」という項目がある。

    このように、ガベージコレクタ自体は実装されていた。ただし、Cocoaなどのフレームワークが対応していなかったため、使用することは事実上できなかったのだが。

    そこで、TigerのObjective-Cランタイムのソースコードをあたってみよう。Darwin 8系の最新であるDarwin 8.10に搭載されている、objc4-274のソースコードを見てみる。すると、objc-auto.mというファイルがある。これが、Objective-Cランタイムでのガベージコレクションを担当しているものになる。

    このファイルには、objc_collectという関数がある。ガベージコレクションを開始するトリガーとなるものだ。そのソースコードを見てみよう。

    objc-auto.m

    void objc_collect(void) 
    {
        if (UseGC) {
            auto_collect(gc_zone, AUTO_COLLECTION_FULL_COLLECTION, NULL);
        }
    }
    

    auto_collectという関数を呼んでいる。この関数の実体はどこにあるのか?

    実は、auto_collectはObjective-Cランタイムの機能では、ない。libautoという、ランタイムとは別の、外部のライブラリに含まれる関数だ。このlibautoライブラリが、ガベージコレクションを実現している。Objective-Cランタイムは、このライブラリの1クライアントという立場になる。libautoは、/usr/lib/libauto.dylibにある※。

    ※このlibautoとObjective-Cランタイムとの関係は、Appleのドキュメント「Garbage Collection Programming Guide: Architecture」にも記述されている。

    では、libautoのソースコードは公開されているかというと、Darwinの状況や、objc-auto.mに書かれているコメントから判断するに、オープンソースではないようだ。

    という訳で、ガベージコレクタの実体がlibautoにあることはわかったが、そのソースコードは得られないようだ。

    ガベージコレクタの統計的情報

    とはいっても、objc-auto.mのソースコードからわかることもいくつかある。たとえば、autostatisticstという構造体の定義がある。これは、libautoで使われているもののようだ。

    objc-auto.m

    typedef struct {
        unsigned    version; // reserved - 0 for now
        /* Memory usage */
        unsigned long long  num_allocs; // number of allocations performed
        volatile unsigned   blocks_in_use;// number of pointers in use
        unsigned    bytes_in_use;       // sum of the sizes of all pointers in use
        unsigned    max_bytes_in_use;   // high water mark
        unsigned    bytes_allocated;
        /* GC stats */
        /* When there is an array, 0 stands for full collection, 1 for generational */
        unsigned    num_collections[2];
        boolean_t   last_collection_was_generational;
        unsigned    bytes_in_use_after_last_collection[2];
        unsigned    bytes_allocated_after_last_collection[2];
        unsigned    bytes_freed_during_last_collection[2];
        auto_date_t duration_last_collection[2];
        auto_date_t duration_all_collections[2];
    } auto_statistics_t;
    

    libautoが管理するオブジェクトの統計的情報を表すもののようだ。メモリの使用状況や、ガベージコレクション発動後の状況が得られるようだ。この構造体の値は、libautoに含まれる関数、auto_collection_statisticsなどを使えば取得できるようだ。

    これらの情報も使いながら、ガベージコレクションの動作を探っていきたい。

    関連したタグ

    新着記事

    特設サイトの情報

      求人情報

      人気記事

      一覧

      イチオシ記事

      新着記事

      特別企画

      転職ノウハウ

      あなたの仕事適性診断

      4つの診断で、自分の適性を見つめなおそう!

      Heroes File ~挑戦者たち~

      働くこと・挑戦し続けることへの思いを綴ったインタビュー

      はじめての転職診断

      あなたにピッタリのアドバイスを読むことができます。

      転職Q&A

      転職に必要な情報が収集できます

      スカウト転職する

      企業からアプローチのメッセージが届きます。

      マイナビニュースマガジン