ガベージコレクションとは
ガベージコレクション(GC)は、コンピュータプログラムが動的に確保したメモリ領域のうち、不要になった領域を自動的に解放する機能です。
プログラマーが明示的にメモリ解放を記述する必要がなく、
メモリ管理の負担を軽減し、メモリ関連のバグを回避するのに役立ちます。1959年頃に
ジョン・マッカーシーによってLISPの問題解決のために発明されました。
ガベージコレクタ
ガベージコレクションを実行する主体は、ガベージコレクタと呼ばれます。これは、タスクやスレッドとして実装されることが一般的です。
メモリコンパクション
メモリの断片化を解消するコンパクションという機能があり、ガベージコレクションと同時に行われることもあります。そのため、コンパクションを含めてガベージコレクションと呼ぶこともありますが、厳密には区別されます。
名称
「ガベージコレクション」は直訳すると「ゴミ集め」となりますが、プログラミング分野では、外来語としてカナ表記やGCという略記が一般的に使用されます。
ガベージコレクションの動作
従来の
メモリ管理では、
プログラマーがメモリの確保と解放を明示的に記述する必要がありました。しかし、ガベージコレクションを利用すると、メモリの確保は
プログラマーが行いますが、解放はガベージコレクタが自動的に行います。ガベージコレクタは、プログラムが今後そのメモリにアクセスしないと判断した場合にメモリを解放します。この判断は、スタックや変数テーブルなどから参照をたどってメモリに到達可能かどうかによって行われます。
ガベージコレクションの機能は、
プログラミング言語の機能として組み込まれている場合や、外部
ライブラリとして提供される場合があります。
ガベージコレクションの特徴
ガベージコレクションは、
プログラマーが明示的にメモリ解放を行う必要がないため、以下のような
メモリ管理に関連するバグを回避できます。
メモリリークの回避: オブジェクトを指し示すポインタがない状態を回避します。
オブジェクトの二重解放の回避: 一度解放したオブジェクトを再度解放することを防ぎます。
無効なポインタの回避: 解放済みのメモリ領域を指すポインタ(ダングリングポインタ)の使用を防ぎます。
ただし、ガベージコレクションを使用しても、不要なオブジェクトへのポインタを保持し続けると、メモリリークが発生する可能性があります。また、多くの実装では、ガベージコレクションが開始されると他の処理を一時停止するため(Stop-the-world GC)、リアルタイムシステムへの適用は難しい場合があります。
ガベージコレクションは、プログラミングスタイルの選択肢を広げる効果もあります。一時的なオブジェクトの生成や、マルチスレッドでのオブジェクト共有をより自然に記述できます。
ガベージコレクションの実装
ガベージコレクションは、言語仕様に組み込まれている場合や、外部ライブラリとして提供される場合があります。ガベージコレクションには、応答時間、スループット、リソース消費など、さまざまな要求があり、それらを満たすためにさまざまなアルゴリズムが提案されています。
代表的なガベージコレクションアルゴリズム
参照カウント: オブジェクトを参照するポインタの数を数え、参照数がゼロになったら解放する方法。循環参照の問題があります。
マーク・アンド・スイープ: オブジェクトから参照をたどり、到達できないオブジェクトを破棄する方法。
コピーGC: 有効なオブジェクトを別のメモリ領域にコピーする方法。メモリ消費量が多いですが、コンパクションを同時に行えます。
これらの
アルゴリズムは、複合して使用されることもあります。例えば、世代別ガベージコレクションでは、コピーGCとマーク・アンド・スイープの両方の
アルゴリズムを使用しています。
ガベージコレクション方式
ストップ・ザ・ワールド: アプリケーションの動作をすべて止めてガベージコレクションを行う方式。
コンカレント: アプリケーション動作と並行してガベージコレクションを行う方式。
言語による利用可能性
一般的に、高レベルな言語ほどガベージコレクションを標準機能として備えていることが多いです。関数型言語や動的言語、オブジェクト指向言語などに広く採用されています。
ガベージコレクションを持つ言語の例
LISP
ML
Haskell
Lua
Ruby
Smalltalk
Java
ECMAScript(
JavaScript)
C#
Visual Basic
.NET
C++や
Delphiは、デストラクタがその代わりとなっています。
RustはGCを持たないものの、所有権システムでメモリを管理します。
Objective-Cは、参照カウントベースのオブジェクト寿命管理機能がありましたが、macOSでは自動参照カウント(ARC)が推奨されています。
Pythonは、参照カウント方式と世代別GCを併用しています。
ガベージコレクションは、言語機能として提供されていない場合、
ライブラリを利用して実装することができます。
Boehm GC: C/C++向けのマーク・アンド・スイープ方式のガベージコレクタ。
スマートポインタ: C++でRAIIを活用した
メモリ管理を行うための
ライブラリ。
分散ガベージコレクション
分散コンピューティング環境では、リモートホスト上に存在するオブジェクトのガベージコレクションも考慮する必要があります。分散ガベージコレクションは、通信が切れた場合などの特殊な状況に対応する必要があります。
世代別ガベージコレクション
従来のガベージコレクションでは、メモリ領域が大きくなるとガベージコレクションの時間が長くなるという問題がありました。世代別ガベージコレクションは、メモリ領域を新領域と古領域に分け、新領域のみを頻繁にガベージコレクションすることで、高速化を図る手法です。
SSDにおけるガベージコレクション
SSD(ソリッドステートドライブ)においても、不要になったデータを消去する際にガベージコレクションが行われます。
参考文献
JIS X 3002:2011「電子計算機プログラム言語COBOL」
JIS X 3015:2008「プログラム言語C#」
関連項目
動的メモリ確保
弱い参照