在阅读西门吹牛和Gityuan的文章之后,总结记录下引用计数算法的循环引用问题。
示例代码如下:
public static void main(String[] args) {
GcObject obj1 = new GcObject(); //Step1
GcObject obj 2 = new GcObject();//Step2
obj1.instance = obj2; //Step3
obj2.instance = obj1;// //Step4
obj1 = null; //Step5
obj2 = null; //Step6
}
当采用引用计数算法时:
- 第一步:GcObject实例1被obj1引用,所以它的引用数+1,为1
- 第二步:GcObject实例2被obj2引用,所以它的引用数+1,为1
- 第三步:obj1的instance属性指向obj2,而obj2指向GcObject实例2,故GcObject实例2引用+1,为2
- 第四步:obj2的instance属性指向obj1,而obj1指向GcOjbect实例1,故GcObject实例1引用+1,为2
到此前4步, GcOjbect实例1和GcOjbect实例2的引用数量均为2,此时结果图如下.
PS:注意想一下,为什么是obj的instance属性,而不是写成obj本身? // 如果是obj本身,则栈中obj1直接指向了堆中的GcObject实例2.
5.第五步:obj1不再指向GcOjbect实例1,其引用计数减1,结果为1.
6.第六步:obj2不再指向GcOjbect实例2,其引用计数减1,结果为1.
到此,发现GcObject实例1和实例2的计数引用都不为0,那么如果采用的引用计数算法的话,那么这两个实例所占的内存将得不到释放,这便产生了内存泄露。
引用计数算法常用来说明垃圾回收算法的机制,但是很少为各种语言所有,其中COM采用的就是引用计数算法.
转自: https://www.cnblogs.com/gudi/p/6414420.html?utm_source=itdadao&utm_medium=referral