浅析Java中 产生循环引用 之后的垃圾回收

Java垃圾回收

在学习Java的过程中,我们都知道了“Java会拾荒”,即垃圾回收:

    创建对象时,它会被存放在称为堆的内存区域,不管对象是如何创建的都会放在此区域中;

    此区域并非不同的堆;它是可以回收垃圾的堆(Garbage-Collectible Heap);

    Java会根据对象的大小来分配内存空间;

    Java会主动帮你管理内存;当某个对象被虚拟机察觉不再被使用,该对象就会被标记为可回收的;

    如果内存开始不足,垃圾收集器就会启动来清理垃圾、回收控件,让空间能够被再次利用;

 

回收机制

某个对象被虚拟机察觉不再被使用的方式有两种:

    实际就是判断对象是否是垃圾的算法;

    1-引用计数算法:

        堆中每个对象都有一个引用计数器;每有一个对象的引用,相应的引用计数+1(相反的情况则-1);

        任何引用计数为0的对象可以被当做垃圾进行收集;

        优点:执行简单、判断高效;

        缺点:难以检测出对象之间的循环引用;

    2.根搜索算法:(现在大多数JVM使用的算法)

        根集(Root Set):正在执行的Java程序可以访问的引用变量的集合(注意不是对象的集合);

        通过一些列的GC Roots对象作为起始点,寻找其他节点,找到之后继续向下寻找其他节点;

        搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链连接时,则此对象不可用;

        

关于JVM:

    在目前发布的Java8中,默认的虚拟机使用的是HotSpot(另一种是JRockit),对应的垃圾回收机制也就是HotSpot的GC机制;

    而JVM HotSpot使用的就是可达性分析法,即根搜索算法;

 

循环引用实践

在学习设计模式的过程中,在观察者模式以及正在学习的状态模式,都使用了类似循环引用的方式,具体实现如下:

    一种是比较经典的产生循环引用的场景;

    另一种是设计模式书中经常使用的场景;

 

总结

我们看到:

    在将引用置null之后,主动调用垃圾回收,两个对象会调用各自的finalize()方法;

    这正与我们前文所述的根搜索算法相对应,被标记为可回收的对象,之后顺利的被垃圾收集器清理掉了;

你可能感兴趣的:(设计模式-深入浅出)