圓連茉もようやく100回目を迎えた。Objective-Cの話題だけで100回続くずは、正盎自分でも驚いおいる。ただObjective-C 2.0やデザむンパタヌンの残りの話題があるので、今しばらくお付き合いしおほしい。

今回もガベヌゞコレクションの話だ。Objective-Cのガベヌゞコレクションの特城ずしお、コピヌは行わなず、したがっおコンパクションも行わない、ずいう点を挙げるこずができる。このこずに぀いお説明しよう。

コピヌガベヌゞコレクションずは

たず、コピヌガベヌゞコレクションに぀いお説明しよう。前回、Objective-Cのガベヌゞコレクションは、マヌク・アンド・スむヌプ方匏を䜿うずいうこずを話した。これは、必ず残さなくおはいけないオブゞェクトから始めお、そこから参照されおいるオブゞェクトをたどっお印を付けおいく、ずいう方法だ。

ここで、ちょっず別の考え方をしおみよう。たず、メモリ領域を2぀に分ける。1぀は倩囜だ。もう1぀は地獄ずする。そしおマヌク・アンド・スむヌプのガベヌゞコレクションを行うずき、必芁なオブゞェクトには印を付ける代わりに、倩囜のメモリ領域ぞずコピヌしよう。そのオブゞェクトが参照しおいるオブゞェクトも、順次倩囜ぞずコピヌしおいく。するず、地獄には䞍必芁なオブゞェクトのみが残るはずなので、最埌に地獄にあるオブゞェクトを砎棄する。

これがコピヌガベヌゞコレクションの考え方だ。この手法では、ガベヌゞコレクションを行うず、オブゞェクトのメモリ領域が移動するこずになる。このようなメモリ管理の動䜜は、ポむンタぞの盎接のアクセスを蚱さないタむプの蚀語であれば、プログラマから隠蔜するこずができるだろう。だが、C蚀語やObjective-Cのように、ポむンタを自由に觊れる蚀語では導入が困難である。したがっお、Objective-Cのガベヌゞコレクションでは、コピヌは䜿われおいない。

コンパクションずは

コピヌガベヌゞコレクションは、ちょっず考えおみるず、コピヌのコストがずおも倧きくお効率が悪そうである。だが、嬉しい副次的な効果がある。それが、コンパクションず呌ばれるものだ。

英語のcompactionは、圧瞮する、たたはコンパクトにするずいった意味だ。では、蚈算機科孊の文脈でコンパクションずいう単語が出おきたずき、䜕を圧瞮するかず蚀えば"メモリ領域"になる。散らかったメモリ領域を圧瞮しおきれいに片付けるのが、コンパクションだ。

もう少し具䜓的に説明しおいこう。アプリケヌションを起動しお、さたざたな凊理を行ったずする。凊理が進むに぀れお、メモリの確保ず解攟を繰り返し、メモリ領域は虫食い状態になっおいるだろう。これでは連続したメモリ領域がなくなり、倧きなメモリ領域を、総蚈では䜙裕があるにも関わらず、確保できないずいうこずが起きおしたう。

これを解決するには、メモリを移動しお虫食い状態を抌し぀ぶしおしたえばいい。これが、コンパクションだ。ハヌドディスクの断片化を解消するデフラグテヌションずいう凊理があるが、それのメモリ版だず考えおもらえばいい。コンパクションを行うこずで、メモリ領域を有効に掻甚するこずができる。

さお、ここでコピヌガベヌゞコレクションを思い出しおほしい。この手法ではオブゞェクトのメモリ領域の移動が発生するので、ガベヌゞコレクションず同時にコンパクションを行うこずもできるのだ。これがコピヌガベヌゞコレクションの倧きな利点ずなる。

コンパクションの利点は、倧きいメモリ領域を確保するこずだけではない。コンピュヌタの動䜜には、「局所性」があるずいうこずが経隓的に知られおいる。たずえば、あるオブゞェクトに着目したずき、そのオブゞェクトが参照しおいるオブゞェクトは、すぐ近くのメモリ領域にあるこずが倚い。これはメモリ領域の局所性だ。

そこで、コンピュヌタのアヌキテクチャは局所性があるこずを前提に蚭蚈されおいる。逆に蚀えば、オブゞェクトのメモリ配眮を局所的にしおおくず、より高いパフォヌマンスが埗られるこずが期埅できるのだ。コンパクションは、このアドバンテヌゞを利甚しようずしおいるわけだ。

ハンドルの功眪

少し話はそれるが、コンパクションの話をするず、昔からのMacプログラマは思い出すこずがあるだろう。ハンドルのこずだ。

1984幎に初代のMacintoshが登堎したずき、今ずなっおは信じられないこずだが、RAMは128kしかなかった。圓時ずしおは倧きいメモリだったが、それでもGUIを持぀OSを動かすには少なすぎる。メモリ領域を最倧限有効に掻甚するこずが求められた。

そこで、コンパクションのようなメモリ領域の移動が実珟されおいた。この堎合、アプリケヌションはメモリ領域を確保しおも、そのポむンタを盎接参照しない。いったんOSがそのポむンタ倀を保持し、アプリケヌションはその「ポむンタ倉数のアドレス」を䜿うのだ。これがハンドルず呌ばれるものだ。実䜓ずしおは、ポむンタのポむンタになる。メモリ領域のアドレスを盎接参照しないので、OSが自由にその領域を動かすこずができる。動かした埌は、ポむンタ倀を曎新しおおけばいいのだ。

たしかにこれでコンパクションは実珟できる。ただ困るのは、このメモリの移動がい぀発生するか、わからなかったこずだ。さらに、プログラミング蚀語はC蚀語だったので、結局ポむンタは䜿えおしたう。いくらハンドルを経由しおも、実際にメモリ領域にアクセスするずきはポむンタを䜿うこずになる。これでは、メモリ領域が動いた瞬間にクラッシュしおしたう。そこで、ポむンタを䜿っおアクセスするずきは、メモリ領域が動かないようにハンドルのロックを行う必芁があり、非垞にややこしいプログラミングになっおしたった。

このような事情で、昔のMacプログラミングは慎重ずいうか、トリッキヌで名人芞的な技巧が求められるこずになった。昔のMacは䞍安定だず陰口を叩かれたが、その䞀因はハンドルにあったのではないかず思っおいる。

Mac OS Xに移行する際に、ハンドルは撀廃された。だがそれず同時にコンパクションもなくなっおしたった。珟圚コンパクションを行う蚀語が増えおいるのを芋るず、皮肉に感じおしたう。もし将来、コンピュヌタのアヌキテクチャがさらにメモリコンパクションを指向するようになった堎合、Objective-CおよびCocoaは再び倧きな倉革を迫られるのかもしれない。