アルゴリズムは、各オブジェクトでオブジェクトが参照された回数を記録します。オブジェクトが 2 番目のオブジェクトを参照している限り、このオブジェクトのカウンタは +1 され、このオブジェクトへの参照がキャンセルされると、カウンタは 2 になります。 -1。いつでも、オブジェクトのカウンタが 0 であれば、オブジェクトは
public static void invoke() {
User a = new User ();
}
public static void main(String[] args) {
invoke();
}
main関数はinvokeメソッドを呼び出し、invokeメソッドではローカル変数aに新しいUserオブジェクトを代入し、このときヒープメモリ上にあるUserオブジェクトのインスタンスのカウンタは+1されます。
メソッドが終了すると、ローカル変数はそれに応じて破棄され、ヒープ メモリ内のオブジェクトのカウンタは -1 になります。
既存の問題
1. 循環参照を処理できません。
2. ヒープ内のオブジェクトのすべての参照割り当てとすべての参照クリアには加算および減算の操作が伴うため、パフォーマンスに一定のオーバーヘッドが生じます。
したがって、Java は GC の実装にこのアルゴリズムを使用しません。
以下のコードのような循環参照の状況を説明しましょう。
class User {
private Order order;
public void setOrder(Order order) {
this.order= order;
}
}
class Order {
private User user ;
public void setUser(User user) {
this.user = user;
}
}
public void method() {
User user = new User();
Order order = new Order();
user.setOrder(user);
order.setUser(order);
}
オブジェクト User はオブジェクト Order を参照し、オブジェクト Order はオブジェクト User を参照します。
メソッドメソッドでは、2 つのセットが実行された後、メソッドメソッドが終了し、図中の 2 本の黒線参照が消え、ヒープメモリ上に 2 つのオブジェクトが循環参照されたままになっていることがわかります。現時点ではそれらを使用する場所がないため、メモリ リークが発生します。二人の被験者は風の中でぐちゃぐちゃになり、途方に暮れていた。
したがって、Java は GC の実装にこのアルゴリズムを使用しません。