ガベージコレクションの仕組み

ガベージコレクションの使い方を見たところで、その仕組みを簡単に説明しよう。

今、あるアプリケーションを起動して、色々な動作をさせるとしよう。プログラムで処理を行うには、オブジェクトを作る必要がある。そうやって、どんどん色々な処理をして、どんどん色々なオブジェクトを作っていくとする。ここでは、retainやreleaseといったCocoa特有のオブジェクト管理は考えないでおく。

さて、ある時点で、アプリケーションの動作を一瞬止めて、オブジェクトの状態を見てみよう。現在使われているオブジェクトもあれば、すでに使われなくなっているオブジェクトもあるはずだ。この、「使われていない」オブジェクトは、メモリ上に散らばる「ゴミ(garbage)」だ。そこで、このゴミを「回収(collection)」して、解放して、再びメモリを使えるようにしよう。これが、ガベージコレクションだ。

なるほど。とても理にかなっている考え方だ。だが、次の疑問がわき上がる。使われているオブジェクトと、使われていないオブジェクトは、どうやって見分けるのだろう?

そこで出てくるのが、「ルートオブジェクト」という考え方だ。ルートオブジェクトは、ガベージコレクションを行う時点で確実に使用中であり、解放の対象にならないオブジェクトだ。たとえば、グローバル領域にあるオブジェクトがそうだし、現在のスタックに積まれているオブジェクトも含まれる。Cocoaアプリケーションならば、NSApplicationのインスタンスなどがそうだろう。

これらのルートオブジェクトが参照しているオブジェクトは、「使用中」と考えることができるだろう。また、それらの使用中オブジェクトが参照しているオブジェクトも、同様に使用中とみなすべきだ。このように、ルートオブジェクトから始めて、参照のリンクをたどっていったオブジェクトは、使用中のオブジェクトとなり、ガベージコレクションの対象から外れる。これらのオブジェクトを、「到達可能(reachable)」なオブジェクトとも呼ぶ。つまり、ガベージコレクションされるのは、到達可能ではないオブジェクト、ということになる。

到達可能なオブジェクトと、到達可能でないオブジェクト

上の図では、AからEのオブジェクトが到達可能、それ以外は到達不可となる。

つまり、ガベージコレクションの世界では、オブジェクトを保持するには到達可能にする、つまり参照を持つこととなり、解放するには到達不可、つまり参照を持たないことで、オブジェクトの管理を行うことになる。しかし、少し考えてみれば、使用するオブジェクトは参照して、使用しないオブジェクトは参照しない、というのはすごく当たり前のことだ。ここから、ガベージコレクションさえ導入すれば、ほぼ何もしなくともオブジェクトの管理が行える、という結論になる訳だ。