参照カウント
出典: フリー百科事典『ウィキペディア(Wikipedia)』
参照カウント(さんしょうカウント、reference counting)は、ガベージコレクタの動作方法の一つ。
- すべてのオブジェクト(メモリ上におかれているデータの単位)に対して、参照カウントと呼ばれる整数値を付加しておく。これは、このオブジェクトへのポインタがシステム全体にいくつ存在しているかを数えるものである。
- オブジェクトへの参照が変化するたびにこの値は随時書き換わる。
- 参照カウントが0になったものについては破棄が許される。
この方法は処理が高速であることが特長である。オブジェクトを多数生成し、すぐに参照を切るような処理においても、参照がなくなったことがその場で検知され、迅速に破棄が起きる。利用できるメモリが少ない状況では大きな利点となる。ただ、不要になったオブジェクト同士が循環参照している場合、参照カウントが0にならないためにオブジェクトが破棄されないという問題がある。
また、参照カウントが頻繁に書き変わる場合には書き換え負荷そのものが問題になる場合もある。さらに、単純な実装では大量のオブジェクトが一斉に解放されることがあり、CPUの空き時間を利用してガベージコレクションを行う方法と比べると、メモリの解放で処理が遅くなってしまう場合もある。
[編集] 参照カウントの問題点
参照カウントには、循環参照により到達不能なデータでも解放できないという問題がある。
class A { public B b; } class B { public A a; } public class Test { public static void main(String[] args) { A a = new A(); // *1* B b = new B(); // *2* a.b = b; b.a = a; a = null; b = null; // *1*、*2*で作成したAとBのオブジェクトは到達不可能にもかかわらず、参照カウントは1 } }
この問題を防ぐためには、多くの言語・システムでウィークリファレンスが導入される。 ウィークリファレンスとは、参照カウントを増加させないポインタである。
[編集] ウィキペディアでの例
ウィキペディアの「孤立した記事」は、参照カウントが0のものを表示しているだけなので、孤立した記事だけから参照されている記事は孤立した記事と見なされていない(これも循環参照の例である)。
上で述べた問題を回避する方法としてマーク・アンド・スイープがある。
[編集] 実用例
- マイクロソフトのComponent Object ModelにおけるCOMオブジェクトは参照カウント方式で管理される。
- プログラミング言語Perlのガベージコレクタは参照カウント方式を用いている。
- プログラミング言語Pythonのガベージコレクタは主に参照カウント方式を用いている。
- Boost C++ Library の shared_ptr<> 及び shared_array<>。
- GLibに含まれるオブジェクトシステムGObjectは参照カウント方式で管理を行う。