首先为什么要去判断一个Java对象是否存活呢?

     这是因为判断一个Java对象是否存活对于垃圾回收、防止内存泄漏等十分重要,垃圾收集器对 Java堆里的对象是否存活进行判断,Java对象存活不回收,死亡则回收。

    判断方式
            在Java虚拟机中,判断对象是否存活有两种方法:
                       1、引用计数法
                       2、引用链法(可达性分析法)

一、引用计数法

1.1方法描述:

      1.给Java对象添加一个计数器引用计数器

      2.每当有一个地方引用它时,计数器+1,引用失效则-1.

1.2判断对象存活准则

      当计数器不为 0 时,判断该对象存活;否则判断为死亡(计数器 = 0)。
1.3 优点
      1.实现简单
      2.判断高效
1.4 缺点
无法解决对象间相互循环引用的问题,会进入死循环(也就是该算法存在着判断逻辑的漏洞)

二、引用链法(可达性分析法)

2.1引用链法主要有三个步骤

      1.可达性分析

      2.第一次标记 & 筛选

      3.第二次标记 & 筛选

2.2方法描述

1、可达性分析

      将一系列的 GC Roots 对象作为起点,从这些起点开始向下搜索。

      GC Roots是什么?常说的GC(Garbage Collector) roots,特指的是垃圾收集器(Garbage Collector)的对象,GC会收集那些不是GC roots且没有被GC roots引用的对象。
可作为 GC Roots 的对象有:
      1.Java虚拟机栈(栈帧的本地变量表)中引用的对象
      2.本地方法栈 中 JNI引用对象
      3.方法区 中常量、类静态属性引用的对象

2.3方法流程

当一个对象到 GC Roots 没有任何引用链相连时,则判断该对象不可达
判断一个对象真正死亡,还需要经过如下两个阶段:

      1.第一次标记 & 筛选

      2.第二次标记 & 筛选

2、第一次标记 & 筛选

标记:
      a.不筛选:继续留在 ”即将回收“的集合里,等待回收;
      b. 筛选:从 ”即将回收“的集合取出
筛选的标准:(该对象是否有必要执行 finalize()方法)
      a.若有必要执行(人为设置),则筛选出来,进入下一阶段(第二次标记 & 筛选);
      b.若没必要执行,判断该对象死亡,不筛选 并等待回收(若没有finalize()方法则认为没必要执行)

3、第二次标记 & 筛选

(当对象经过了第一次的标记 & 筛选,会被进行第二次标记 & 准备被进行筛选)
方法描述:
      该对象会被放到一个 F-Queue 队列中,并由 虚拟机自动建立、优先级低的Finalizer 线程去执行 队列中该对象的finalize()。有两点需要注意:
      ①:finalize()只会被执行一次
      ②:并不承诺等待finalize()运行结束。这是为了防止 finalize()执行缓慢 / 停止,使得 F-Queue队列其他对象永久等待。
筛选标准:
      在执行finalize()过程中,若对象依然没与引用链上的GC Roots 直接关联或间接关联(即关联上与GC Roots 关联的对象),那么该对象将被判断死亡,不筛选(留在”即将回收“集合里并等待回收