ガベージコレクション
出典: フリー百科事典『ウィキペディア(Wikipedia)』
ガベージコレクション(garbage collection; GC)とは、プログラムが動的に確保したメモリ領域のうち、不要になった領域を自動的に解放する機能である。「ガベージコレクション」を直訳すれば「ゴミ収集」となる。
なお本来の英語の発音に近い表記は「ガーベジコレクション」あるいは「ガーベッジコレクション」であると思われるが、日本では、一般には「ガベージコレクション」または「ガーベージコレクション」と表記されることが多い。
メモリの断片化を解消する機能と併せてガベージコレクションと呼ぶ場合もあるが、厳密にはそのような機能はコンパクションと呼び、区別される。実現手法の一つであるコピーGCでは、ガベージコレクションと共にコンパクションも行われる仕組みになっている。
また、ガベージコレクションを行う主体はガベージコレクタと呼ばれる。ガベージコレクタはタスクやスレッドとして実装される場合が多い。
なお、似たようなものにスマートポインタ(smart pointer)があるが、これはライブラリとして提供されるガベージコレクションの一種である。
目次 |
[編集] 利点と欠点
ガベージコレクションはプログラム作成者が明示的にメモリの確保・解放を行う必要が無いため、以下に示すメモリ管理に関連する陥りやすいバグを回避することができる。
- メモリリークの回避。ガベージコレクションは、オブジェクト(データを格納したメモリ領域)とそれを指し示すポインタを管理するため、オブジェクトは存在しているがそれを指すポインタが無い状態を回避することができる。
- オブジェクトの二重解放の回避。いったん解放したオブジェクトをさらに解放することを防ぐ。
- 無効なポインタの回避。例えば、サブルーチンで確保したオブジェクトへのポインタを呼び出し元に戻す場合に、確保したオブジェクトがローカル変数のため、サブルーチンを抜けるとオブジェクトが破棄されることがある。呼び出し元に戻されたポインタにはあるアドレスが代入されているが、そのアドレスにはオブジェクトが存在せず、ポインタは無効なメモリアドレスを指している。このような無効なポインタをDangling pointerといい、ガベージコレクションはこの問題を回避する。
ガベージコレクションは、ある種のメモリリークに対して有効であるが、今後使用することの無いオブジェクトへのポインタを保持し、いつまでもオブジェクトを解放せず、そのようなオブジェクトが増えていきメモリ不足に陥るという問題を回避することはできない。これは論理的な設計の問題であり、ガベージコレクションを持つ言語処理系においてもこの種のメモリリークは発生する。
メモリ管理に関するバグを回避する以外に、プログラミングスタイルの選択肢を広げる効果も持つ。型変換などのために一時的なオブジェクトを生成する、マルチスレッドを利用したプログラムでスレッド間でオブジェクトを共有して使用する、といった処理はメモリ確保・解放の処理の記述が煩雑となることが多い。しかし、ガベージコレクションを持つ言語処理系においては煩雑な記述を省略することができ、これらの処理をより自然に記述することができる。
ガベージコレクションはプログラムの本来の動作とは別に時間のかかる処理であり、実装によっては一旦処理が開始されると他の処理を止め、CPUを長時間(数百ミリ秒から数十秒)占有することもある。さらに、ガベージコレクションの動作タイミングの予測やCPUの占有時間の事前予測などが困難なことから、デッドラインが決められているリアルタイムシステムには向いていない。
[編集] 実装
ガベージコレクションは、Java言語のように言語処理系に組み込まれたものと、C言語のように言語処理系には存在しないがライブラリを使用することで実現できるものがある。
ガベージコレクションは、プログラム本来の動作とは別に時間のかかる処理である。そこで、ガベージコレクションには本来のプログラムの動作に対して影響が少ないことが求められる。
一般に、デスクトップアプリケーションでは、応答時間を短くするため、ガベージコレクションによるプログラムの停止時間を最小にすることが要求される。また、サーバアプリケーションでは、応答時間よりもスループットを求められることが多く、ガベージコレクションにもスループット性能が高いものが求められる。さらに、機器組み込みアプリケーションでは、機器に搭載されるCPUの能力が低さやメモリ容量の小ささから、リソース消費が小さいものが求められる。また、リアルタイムシステムでは、プログラム動作時間のばらつきを最小にしたいという要求もある。
これらの要求をすべて満たすようなアルゴリズムは存在しないため、さまざまな手法が提案されている。代表的なガベージコレクションアルゴリズムには、以下のものがある。
- 参照カウント。オブジェクトを参照するポインタの数を数え、参照するポインタの数がゼロになったら解放する方法。循環参照の問題がある。解放が集中したときに、単純な実装だと停止時間が長くなる。
- マーク・アンド・スイープ。オブジェクトから別のオブジェクトへの参照をたどり、到達出来ないオブジェクトを破棄する方法。
- コピーGC。通常使用するメモリ領域と同じ容量のメモリ領域をもうひとつ用意し、ガベージコレクションの際に有効なオブジェクトのみをもう一方のメモリ領域にコピーする方法。メモリ領域をデータ保持に必要な容量の2倍消費すること、コピーの際にオブジェクトのアドレスが変更されることなどの欠点があるが、ガベージコレクションとコンパクションが同時に行える利点がある。
これらのアルゴリズムは複合して使用することもあり、世代別ガベージコレクションではコピーGCとマーク・アンド・スイープの両方のアルゴリズムを使用している。
また、アプリケーション動作への影響の観点から、アプリケーション動作をすべて止めるStop the world方式と、アプリケーション動作と並行して動作するコンカレント方式に分類することができる。
[編集] GCを実装した言語・処理系の例
- ActiveBasic (Ver5.0~)
- ActionScript (Flashプレーヤ5以降)
- CLI (Common Language Infrastructure)
- Curl
- D言語
- Java
- JavaScript
- LISP
- Lua
- MS-BASIC
- Objective-C(2.0以降)
- Perl
- Python
- Ruby
- Smalltalk
- Squirrel
[編集] ライブラリ
- Boostのsmart_ptr - C++用。参照カウント。
- Boehm-Demers-Weiser conservative garbage collector - C/C++用。マーク・アンド・スイープ。
[編集] 分散ガベージコレクション
分散コンピューティング環境では、あるホスト内のオブジェクトだけではなく、リモートホスト上に存在するオブジェクトとメッセージのやり取りが行われることがある。このような環境においてローカルなガベージコレクションと同様、不要なオブジェクトを破棄する手法が分散ガベージコレクションである。リモートホストからの参照状態の検出、通信が切れた場合の処理などローカルホストのガベージコレクションとは異なる課題を解決する必要がある。

