参照カウントをベースにした
メモリ管理アルゴリズム
Qiita の記事の付属資料として作成しました。
A
B
C
A
オブジェクトAを表す
側にある数字は参照カウント (RC)
0
0
2
1
ROOT
A
B
C
E
D
H
G
F
初期配置
2
1
2
1
1
2
1
1
ROOT
A
B
C
E
D
H
G
F
ROOTからAとD、Gの参照が切れると
それぞれの参照カウントが減る。
1
1
2
0
1
1
1
1
ROOT
A
B
C
E
D
H
G
F
1
1
2
0
1
1
1
Dの参照カウントが0になったため、
Dは回収され、Eの参照カウントが減る。
ROOT
A
B
C
E
H
G
F
1
1
1
1
1
1
EもD同様回収され、Cの参照カウントが減る。
ROOT
A
B
C
H
G
F
1
1
1
1
1
1
AとGおよびCは参照カウントが1以上なので
循環参照の疑いありとしてマークされる。
ROOT
A
B
C
H
G
F
1
1
1
1
1
1
試験削除 (Partial Mark and Sweep) の実施
試験削除中はRCが0になっても回収されないことに注意。
ROOT
A
B
C
H
G
F
1
0
1
1
1
1
対象オブジェクトが灰色でなければ灰色にマークし、リンク先の RC を減らす。
PaintGray(対象: A)
ROOT
A
B
C
H
G
F
1
0
0
1
1
1
Bに対してもA同様、灰色にマークし、リンク先のRCを減らす。
PaintGray(対象: B)
ROOT
A
B
C
H
G
F
0
0
0
1
1
1
Cも同様。次はCのリンク先であるAを対象にするが、Aはすでに灰色なのでここでPaintGrayは終了となる。
PaintGray(対象: C)
ROOT
A
B
C
H
G
F
0
0
0
1
1
1
Aは灰色かつRCが0のため、回収候補に加える。
ScanGray(対象: A)
ROOT
A
B
C
H
G
F
0
0
0
1
1
1
次にAのリンク先Bに対して、ScanGrayを実施。
Bも同様に回収候補となる。
ScanGray(対象: B)
ROOT
A
B
C
H
G
F
0
0
0
1
1
1
Cも同様。次はAだが灰色ではないので、
ここでScanGrayは終了。
ScanGray(対象: C)
ROOT
A
B
C
H
G
F
0
0
1
1
1
Aは回収候補としてマークされているため、
回収する。リンク先も同様にチェックしていく。
CollectWhite(対象: A)
ROOT
H
G
F
1
1
1
A、B、Cの回収が完了。
次はGについて試験削除を試みる。
ROOT
H
G
F
1
0
1
Gは灰色でないため灰色にマーク。
リンク先HのRCを減らす。
PaintGray(対象: G)
ROOT
H
G
F
1
0
1
Hも灰色でないため灰色にマークするが、
リンク先はないためPaintGrayはここで終了。
PaintGray(対象: H)
ROOT
H
G
F
1
0
1
Gは参照カウントが0ではないため、PaintBlackを実施。
ScanGray(対象: G)
ROOT
H
G
F
1
1
1
Gを黒くマークし、リンク先Hの参照カウントを増やす。Hが黒くマークされていないので、Hに対してもPaintBlackを実施。
PaintBlack(対象: G)
ROOT
H
G
F
1
1
1
Hを黒くマークするが、リンク先はないためPaintBlackはここで終了。
PaintBlack(対象: H)
ROOT
H
G
F
1
1
1
Gは回収候補でないため、CollectWhiteは終了。
CollectWhite(対象: G)
ROOT
H
G
F
1
1
1
最終的にこのようになる。