マーク・アンド・スイープ(mark-and-sweep)は、プログラミングにおける
ガベージコレクションの方式の中でも一般的な手法です。この技術は、無用なオブジェクトを特定し、システムのメモリを効率的に管理する目的で用いられます。ここでは、その基本的なプロセスや特徴、並びに関連する実装について詳述します。
方法論
マーク・アンド・スイープの基本的な流れは、特定のオブジェクトから始まり、そのオブジェクトに参照される他のすべてのオブジェクトを辿って、各オブジェクトに印をつけます。このプロセスを以下の手順で行います。
1.
ルートオブジェクトへの印付け: まず、プログラム内のルートオブジェクトに印をつけます。これはプログラムの実行中に参照可能なオブジェクトです。
2.
トラバース: 最初に印をつけたオブジェクトから、参照を持つ他のオブジェクトも辿り、到達可能な全てのオブジェクトに印をつけていきます。既に印がついているオブジェクトに対しては再度の処理は行いません。
3.
印の付け直し: 印がつかなかったオブジェクトが見当たらなくなるまで、トラバースと印付けを繰り返します。
4.
不要オブジェクトの削除: 最後に、印がついていないオブジェクトは不要と見なされ、システムから解放されます。
特徴
マーク・アンド・スイープは、特に
参照カウントを用いた方法における
循環参照の問題を回避する利点があります。これにより、不要なオブジェクトを確実に解放できる一方、ガベージコレクタが動作しない時には処理が高速であるため、効率的なメモリ管理が実現します。
ただし、実行には時間がかかるため、以下のようなタイミングで実施されます。
- - メモリ不足時
- - システムがアイドル状態の時
- - プログラムから明示的に指令があった場合(例えば、Javaの`System.gc()`メソッド)
また、マーク・アンド・スイープにおける制約として、オブジェクトの数が増えると処理時間が増大すること、さらに、GC処理中はアプリケーション全体が一時的に停止する必要がある(いわゆる「ストップ・ザ・ワールド」)点があります。
保守的なガベージコレクタ
C言語や
C++のように、ガベージコレクタが標準で実装されていない言語では、マシンスタックやレジスタ内の参照を確認する必要があります。しかし、これらの値が参照アドレスを示しているか、ただの整数を示しているかを区別するのは困難です。このため、こうした言語におけるマーク・アンド・スイープは「保守的なガベージコレクタ」として実装されます。具体的には、掲示されている手順は次の通りです。
1. 確実に使用中の参照を調査し、到達可能なオブジェクトに印をつけます。
2. スタックやオブジェクト内にある全てのデータを参照と見なして処理を進めることで、誤って使用中のメモリを解放しないよう注意が払われます。
3. 使用中でないメモリの一覧を作成し、このリストを基に解放していきます。
代表的な実装
Boehm-Demers-Weiser Conservative Garbage Collectorは、1980年代から利用されているC/
C++向けの保守的なガベージコレクタの一例です。この実装は、その信頼性と効率を兼ね備えた手法として広く利用されています。
まとめ
マーク・アンド・スイープは、現代のプログラミングにおいて重要な
ガベージコレクション技術の一つです。プログラムのメモリ管理を効率的に行うために、多くのプログラミング環境で採用されています。