【マークアンドスイープ】

マーク&スイープ とは?

💡 迷子のオモチャを見つけ出す、お片付けの二段階作戦
📌 このページのポイント
マーク&スイープ GC ① マークフェーズ ルート A ✓ B ✓ C ✓ D E 到達可能(マーク済み) 到達不能(未マーク) ② スイープフェーズ A ✓ B ✓ C ✓ D × E × D, E のメモリを解放 → 再利用可能 処理の流れ プログラム実行 Stop The World マーク スイープ 再開
マーク&スイープのイメージ
ひよこ ひよこ

マーク&スイープって何?名前がお掃除っぽいね!

ペンギン先生 ペンギン先生

まさにお掃除の仕組みだよ。部屋の中で「使っているもの」にシールを貼って(マーク)、シールがないものをゴミ袋に入れる(スイープ)というイメージだね。

ひよこ ひよこ

「使っている」ってどうやって判断するの?

ペンギン先生 ペンギン先生

プログラムの出発点(ルートと呼ぶよ)から参照をたどっていくんだ。グローバル変数やスタック上の変数がルートで、そこから芋づる式にたどれるオブジェクトはすべて「生きている」と判断されるよ。

ひよこ ひよこ

参照カウントとの違いは何なの?

ペンギン先生 ペンギン先生

参照カウントは「自分を参照している数」を常に管理するけど、マーク&スイープは定期的にまとめてチェックするんだ。大きな違いは循環参照を正しく回収できること。AとBがお互いだけを参照していても、ルートからたどれなければ回収されるよ。

ひよこ ひよこ

それはすごい!でもまとめてチェックするって、その間プログラムは動けないの?

ペンギン先生 ペンギン先生

いいところに気づいたね。GC実行中はプログラム全体が一時停止する「Stop The World(STW)」が発生するんだ。ヒープが大きいほど停止時間が長くなるから、リアルタイム性が求められるゲームや金融システムでは大問題になるよ。

ひよこ ひよこ

じゃあ現代の言語ではどうやって改善しているの?

ペンギン先生 ペンギン先生

Javaの世代別GCが代表的だよ。オブジェクトを「若い世代」と「古い世代」に分けて、若い世代だけ頻繁にGCすることでSTWを短くしている。GoのGCはプログラムと並行してマークする「コンカレントGC」を使っていて、停止時間が数百マイクロ秒まで短縮されているんだ。

ひよこ ひよこ

マーク&スイープ以外のGC方式もあるの?

ペンギン先生 ペンギン先生

「マーク&コンパクト」はスイープ後にメモリの断片化を防ぐために生きているオブジェクトを詰め直す方式、「コピーGC」は生きているオブジェクトだけ別領域にコピーする方式があるよ。どれもマーク&スイープの考え方が土台になっていて、1960年にジョン・マッカーシーが考案した歴史あるアルゴリズムなんだ。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「マーク&スイープ」って出てきたら「使っているものに印を付けて、印のないものを捨てるGCの基本方式」と思えればだいたいOK!
📖 おまけ:英語の意味
「Mark-and-Sweep」 = 印付けと掃き掃除
💬 「mark(印を付ける)」してから「sweep(掃く)」という2ステップがそのまま名前になっているよ
← 用語集にもどる