该算法会在每一个对象上记录这个对象被引用的次数,只要有任何一个对象引用了次对象,这个对象的计数器就+1,取消对这个对象的引用时,计数器就-1。任何一个时刻,如果该对象的计数器为0,那么这个对象
public static void invoke() {
User a = new User ();
}
public static void main(String[] args) {
invoke();
}
main函数调用invoke方法,invoke方法中new了一个User的对象,赋值给局部变量a,此时堆内存中的对象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。
method方法中,执行完两个set后,method方法结束,图中两条黑线引用消失,可以看到,留下两个对象在堆内存中循环引用,但此时已经没有地方在用他们了,造成内存泄漏。两个对象就凌乱在风中不知所措了。
?所以Java没有使用这种算法来实现GC。
|