欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

引用计数法的循环引用问题

程序员文章站 2022-05-06 16:51:48
...

引用计数法

关于引用计数法,我们可以先看一段wiki上的描述:

As a collection algorithm, reference counting tracks, for each object, a count of the number of references to it held by other objects. If an object's reference count reaches zero, the object has become inaccessible, and can be destroyed.

When an object is destroyed, any objects referenced by that object also have their reference counts decreased.

       作为一种回收算法,引用计数法记录着每一个对象被其它对象所持有的引用数。如果一个对象的引用计数为零,那么该对象就变成了所谓的不可达对象,亦即可以被回收的。

       当一个对象被回收后,被该对象所引用的其它对象的引用计数都应该相应减少。

       而所谓的循环引用(circular referrence)有是什么意思呢?举个简单的例子:

public class MyObject {
    public Object ref = null;
    public static void main(String[] args) {
        MyObject myObject1 = new MyObject();
        MyObject myObject2 = new MyObject();
        myObject1.ref = myObject2;
        myObject2.ref = myObject1;
        myObject1 = null;
        myObject2 = null;
    }
}

       从上面的代码可以轻易地发现myObject1与myObject2互为引用,我们知道如果采用引用计数法,myObject1和myObject2将不能被回收,因为他们的引用计数无法为零。

引用计数法的循环引用问题

       但是具体是为什么呢?已上图为例,当代码执行完line7时,两个对象的引用计数均为2。此时将myObject1和myObject2分别置为null,以前一个对象为例,它的引用计数将减1。若要满足垃圾回收的条件,需要清除myObject2中的ref这个引用,而要清除掉这个引用的前提条件是myObject2引用的对象被回收,可是该对象的引用计数也为1,因为myObject1.ref指向了它。以此类推,也就进入一种死循环的状态。

可达性分析

为了解决引用计数法的循环引用问题,Java 使用了可达性分析的方法。通过一系列的“GC roots” 对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。

要注意的是,不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记过程。两次标记后仍然是可回收对象,则将面临回收

原文链接https://blog.51cto.com/thatmonkey/1384463

相关标签: GC