ガベコレ調査報告

さてさて、今回もABでどのようなGCを採用するのがよいかという話題で突き進みます。まずは私なりに考えるGCへの要望をまとめたいと思います。

  1. 解放のタイミングの一切をシステムに任せる。
  2. GCシステムにより確保されたメモリへのアクセス違反は原則として起こらない。
  3. 従来のmalloc/free、new/deleteと仲良く使い分けることが出来る。
  4. 安定した処理速度を有するアプリケーションを除き、ストレスのないGC処理を行う。
  5. 他言語間のやり取りで問題が起きないようにする。


これらの要素を順に解説していきましょう。


まず、解放のタイミングを気にしなくて良いという点ですが、これこそがGCであることのメリットであり、大きな特徴です。生産性の向上、デバッグに費やす時間の軽減が期待できることでしょう。


2つ目、GCで管理されるメモリ領域の信頼性の問題ですが、これもGCそのものの特徴といっても過言ではありません。しかし、実は3番目の要素と関連性がありそうな予感…。


お感じになった方もいらっしゃるとは思いますが、GCを採用する言語って、基本的にはfreeやdeleteとは無縁です(JavaC#にはdeleteがありません)。中には、「無理やり行わないように」と注意書きがあるものも・・・。


実は、GCの構造上、GCが管理しないメモリ空間ほど怖いものはないのです。例えば、GCで確保したポインタ値をファイルに書き込み、後々アクセスするなどの処理はアウトです。つまりはファイル内のデータはGCシステムとは無縁であり、GC発動時に不要なメモリとして扱われる可能性が高いからです。このように、GCは自身が管理するもの以外の場所へ管理すべきポインタが格納されるとお手上げ状態になります(セーフティ機能が言語に求められる場面といってもよいでしょう)。


そうなると、3番目に挙げる要素を完全に達成するのは、ネイティブコンパイラであるABにとっとは、ちょっと厳しいのかもしれません。この問題に大しては、間違いにくいコーディング作法を推進していくなどの策をとり、対処を行っていく必要がありそうです。


4番目は処理速度とGC発動のタイミングの問題です。mark&sweepをベースにGCを構築すると、GC発動に対して一定期間のアプリケーションの停止が余儀なく行われることになります。この問題は、コピーGCや世代別GCなどでの対処が伺えますが、スループットの低下や、なによりも私がGCの本質を十分に理解していく必要があるため、完成物を作り出すには相応の時間がかかります。まぁ、コマ落ちが致命的になるようなゲームシステムなどは、GCをオフにした状態でメモリ管理を行ってもらう(少なくともメインループだけでも)という方向性で、当面の間は大丈夫だと捉えるより他ありませんね。


5番目の問題も後々に厄介になりそうです。「GCはここまで管理していますよ」ということを明確にしていかなければ、誰がどのタイミングで各メモリを解放するのかが明確になりません。完璧なOS、言語環境があるとすれば、メモリ管理のすべてがGCによって行われ、例外のケースが発生しないということ。これにつきます。


まぁ、そうはいっても無理難題もあるわけでして、GCとは今後うまい付き合い方をしていきたいと思っています。GCを作る側は山済みになった問題を地道に回避していくだけの根気強さ、発想の転換ができなければならないですね。