GC(1)、引用计数法和可达性分析算法

作者: 编程界的小学生 | 来源:发表于2017-09-05 13:47 被阅读277次

一、概述
程序计数器、虚拟机栈、本地方法栈。这几个区域完全不用管回收问题,因为方法结束或者线程结束的时候他们所占用的内存就自然跟着一起释放了,3个区域随线程而生,随线程而灭。所以我们只需要管堆和方法区。尤其是堆,因为一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个分支需要的内存也可能不一样,这部分内存的分配和垃圾回收都是动态的。

二、引用计数法(ReferenceCounting)

1、算法
给对象中添加一个引用计数器,每当有一个地方引用他时,计数器值就+1,;当引用失效时,计数器值就-1;任何时刻计数器为0的对象就是不可能在被使用。

2、图解

Paste_Image.png

3、优缺点
(1)、优点
判定效率很高
(2)、缺点
不会完全准确,因为如果出现两个对象相互引用的问题就不行了。如下代码所示:

/**
 * testGC()方法执行后会不会被GC?  不会!!!!
 *
 * @author TongWei.Chen 2017-09-05 11:15:53
 */
public class ReferenceCountingGC {

    public Object instance = null;

    public static void testGC() {
        
        //step 1
        ReferenceCountingGC objA = new ReferenceCountingGC();
        //step 2
        ReferenceCountingGC objB = new ReferenceCountingGC();
        //相互引用
        //step 3
        objA.instance = objB;
        //step 4
        objB.instance = objA;

        //step 5
        objA = null;
        //step 6
        objB = null;

        //假设在这行发生CG,objA和objB是否能被回收?   不能!!!!
        System.gc();
    }

    public static void main(String[] args) {
        testGC();
    }
}

(4)、分析上述代码

step1:objA的引用+1   =1
step2:objB的引用+1   =1

step3:objB的引用+1   =2
step4:objA的引用+1   =2

step5:objA的引用-1   =1
step6:objB的引用-1   =1

很明显,到最后两个实例都不再用了(都等于null了),但是GC却无法回收,因为引用数不是0,而是1,这就造成了内存泄漏。也很明显,现在虚拟机都不采用此方式。

三、可达性分析算法(Reachability Analysis)
1、算法
通过一系列的GC Roots的对象作为起始点,从这些根节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

2、图解

Paste_Image.png

说明:
(2.1)、红色代表不可达对象(可回收对象)
(2.2)、千万注意!!!!!上图并不是说方法区全可达,虚拟机栈部分可达,本地方法栈全部不可达,而只是为了说明这三个部分可以作为GC Roots!

3、可以作为GC Roots的对象包括以下几点
(3.1)、虚拟机栈(栈帧中的本地变量表)中引用的对象。
(3.2)、方法区中的类静态属性引用的对象或者常量引用的对象。
(3.3)、本地方法栈中JNI(就是native方法)引用的对象。

若有兴趣,欢迎来加入群,【Java初学者学习交流群】:458430385,此群有Java开发人员、UI设计人员和前端工程师。有问必答,共同探讨学习,一起进步!
欢迎关注我的微信公众号【Java码农社区】,会定时推送各种干货:


qrcode_for_gh_577b64e73701_258.jpg

相关文章

  • 送给Android程序员2021全新整理的面试合集,只为助力年后

    垃圾回收算法 标记算法: 引用计数法 可达性分析法(注意GC root的类型,虚拟机栈和本地方法栈引用的对象、静态...

  • 图解垃圾回收

    为什么要学习 GC ? 常用的垃圾回收算法 引用计数法 可达性分析法 标记-清除(Mark-Sweep) 优化:多...

  • Android 性能优化-GC确定回收的算法

    本文中分享两种GC确定回收的算法 引用计数算法以及可达性分析算法 引用计数算法:简单来说引用计数算法就是当前内存地...

  • 2.2 对象存活判断

    1. 引用计数算法。无法解决仅仅互相引用的问题。 2. 可达性分析算法。可以通过GC Roots到达的即存活,否则...

  • 垃圾收集

    判断对象是否已死: 引用计数法(很难解决对象之间相互循环引用的问题) 可达性分析算法 可作为GC Roots的对象...

  • java架构知识总结--jvm相关(回收部分)

    目的 回收机制整理 知识概括: 必须掌握知识概括 标记算法引用计数法分析可达性算法gc root有:虚拟机栈静态方...

  • 深入理解jvm-笔记

    对象存活判断 1.引用计数(循环引用) 2.可达性分析算法 GC Roots包括栈中本地变量、类静态属性、常量引用...

  • JVM-垃圾回收算法

    一、对象已死吗? JVM中判断对象是否存活有两种算法:引用计数法、可达性分析算法。 1.引用计数法(Referen...

  • JAVA GC机制

    1、需要GC的内存区域:JAVA堆和方法区 2、GC的对象:引用计数和可达性分析 (1)引用计数:每个对象有一个引...

  • JVM-对象已死判断

      1)引用计数器法(无法解决循环引用) 2)枚举根节点做可达性分析。  GC Roots:一组必须活跃的引用。 ...

网友评论

    本文标题:GC(1)、引用计数法和可达性分析算法

    本文链接:https://www.haomeiwen.com/subject/xzhujxtx.html