美文网首页
判断Java对象是否存活的算法

判断Java对象是否存活的算法

作者: Chengyu_l | 来源:发表于2017-08-08 17:57 被阅读0次

声明:本文摘抄自《深入理解Java虚拟机》一书,本文完全为自我学习,请感兴趣的同学购买正版,支持原创

判断对象是否存活的算法包括:

  1. 引用计数算法
  2. 可达性分析算法

引用计数算法(Reference Counting)

给对象中添加一个引用计数器,每当有一个地方引用它时,计数器加1;当引用失效时,计数器值减1;任何时刻计数器为0的对象就是不能再被引用的。例如Object-C,Python语音使用引用计数算法进行内存管理。Java虚拟机没有选用引用计数器算法来管理内存,其中最主要的原有是它很难解决对象之间相互循环引用的问题。

对象循环引用代码示例:

public class ReferenceCountingGC {
    public Object instance = null;
    
    public static void testGC() {
        ReferenceCountingGC objA = new ReferenceCountingGC();
        ReferenceCountingGC objB = new ReferenceCountingGC();
        objA.instance = objB;
        objB.instance = objA;
        
        objA = null;
        objB = null;
        
        // 假设在这行发生GC, objA 和 objB是否能被回收?
        System.gc();
    }
}

对象objA和objB都有字段instance,赋值令 objA.instance = objB及objB.instance = objA,除此之外,这两个对象再无任务引用,实际上这两个对象已经不可能再被访问,但是它们因为相互引用着对方,导致它们的引用计数都不为0,于是引用计数算法无法通知GC收集器回收它们。

可达性分析算法(Reachability Analysis)

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

左侧为仍然存活的对象,右侧为可回收的对象

生成还是死亡

即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。
  如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中。并在稍后由一个虚拟机自动建立的,低优先级的Finalizer线程去执行它。这里所谓“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原有是,如果有一个对象在finalize()方法中执行缓慢,或者发生死循环,将可能会导致F-Queue队列中其他对象永久处于等待,甚至导致整个内存回收系统崩溃。
  finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象这个时候,未被重新引用,那它基本上就真的被回收了。

回收方法区

Java虚拟机规范中确实说过可以不要求虚拟机在方法区中实现垃圾回收,而且在方法区中进行垃圾回收的“性价比”一般比较低,方法区的垃圾收集主要回收两部分内容:废弃的常量和无用的类。

废弃的常量,以常量池中字面量的回收为例,假如一个字符串“abc”已经进入常量池中,但是当前系统已经没有任何一个String对象叫做“abc”的,也没有任何其他地方引用这个字面量,这个“abc”常量就会被清理出常量池。

判断一个无用的类需要同时满足下面3个条件才能算是“无用的类”

  • 该类的所有实例都已经被回收
  • 加载该类的ClassLoader已经被回收
  • 该类对应的java.lang.Class对象已经没有任何地方被引用,无法在任何地方通过反射访问该类的方法。

相关文章

  • GC算法

    主要关注点: 对象存活判断 GC算法 垃圾回收器 对象存活判断 判断对象是否存活一般有两种方式: 引用计数:每个对...

  • Java内存模型

    本文主要介绍 1.Java虚拟机内存区域 2.判断对象是否存活算法 3.GC算法 一.Java虚拟机内存区域划分 ...

  • Java GC 判断对象是否存活

    Java对象是否存活的判断算法——根搜索算法。这个算法的思路其实很简单,它把内存中的每一个对象都看作一个节点,并且...

  • 判断Java对象是否存活的算法

    声明:本文摘抄自《深入理解Java虚拟机》一书,本文完全为自我学习,请感兴趣的同学购买正版,支持原创 判断对象是否...

  • 06-判断对象是否已死

    一、引用计数算法 Java虚拟机并不是通过引用计数算法来判断对象是否存活的 二、可达性分析算法(Reachabil...

  • JVM系列:垃圾收集器与内存分配策略

    判断对象是否存活 引用计数算法 实现简单,判定效率高 Java虚拟机没有使用,主要原因是此算法很难解决对象之间相互...

  • java的四种引用

    无论是通过引用计数算法判断对象的引用数量,还是通过可达性分析算法判断对象是否引用链可达,判定对象是否存活都和“引用...

  • 二、垃圾收集器与内存分配策略

    一、Java采用可达性算法 虚拟机采用可达性分析来判断对象是否存活的。 它们已GC root对象为起点,向下搜索所...

  • JVM:判断一个Java对象是否存活

    前言 如何判断一个Java对象是否存活对于垃圾回收、防止内存泄漏等十分重要 本文将全面讲解判断Java对象存活的方...

  • Java 内存回收算法

    一、判断Java中对象存活的算法 1、引用计数器算法: Java 堆 中每个具体对象(不是引用)都有一个引用计数器...

网友评论

      本文标题:判断Java对象是否存活的算法

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