jvm垃圾回收之如何判定变量是否可以被回收-引用计数法,可达性分析法

   从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。 Major GC 是清理永久代。Full GC 是清理整个堆空间—包括年轻代和永久代。

 

引言

JVM中的堆和方法区主要用来存放对象(方法区中也储存了一些静态变量和全局变量等信息),那么我们要使用GC算法对其进行回收时首先要考虑的就是该对象是否应该被回收。即判断该对象是否还有其他的引用或者关联使得该对象处于存活状态,我们需要将不在存活状态的对象标记出,以便GC回收。

引用计数法

在对象头处维护一个counter,每增加一次对该对象的引用计数器自加,如果对该对象的引用失联,则计数器自减。当counter为0时,表明该对象已经被废弃,不处于存活状态。这种方式一方面无法区分软、虛、弱、强引用类别。另一方面,会造成死锁,假设两个对象相互引用始终无法释放counter,永远不能GC。

可达性分析算法

通过一系列为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明该对象是不可用的。如果对象在进行可行性分析后发现没有与GC Roots相连的引用链,也不会立刻死亡。它会暂时被标记上并且进行一次筛选,筛选的条件是是否与必要执行finalize()方法。如果被判定有必要执行finaliza()方法,就会进入F-Queue队列中,并有一个虚拟机自动建立的、低优先级的线程去执行它。稍后GC将对F-Queue中的对象进行第二次小规模标记。如果这时还是没有新的关联出现,那基本上就真的被回收了。

可达性分析算法是通过枚举根节点来实现的,最重要的问题是GC停顿。为了确保一致性(即所有对象之间的关系是确定下来的)而导致GC进行时必须进行停顿。在HotSpot的中,使用OopMap的数据结构存储特定位置上的调试信息,存储栈上那个位置原来是什么东西,这个信息是在JIT编译时跟机器码一起产生的。因为只有编译器知道源代码跟产生的代码的对应关系。 这样,GC在扫描时就可以得知这些信息了。这样做的目的是使HotSpot能够快速准确的完成GC Roots枚举,以期望减少GC停顿所带来的影响。HotSpot没有在所有的指令生成OopMap,所以只是在“特定位置”记录这些信息,这些位置就是安全点。程序执行时并非在所有的位置上都能停顿下来GC,只有在到达安全点时才能暂停。安全点选取基本上是以“是否让程序长时间执行的特征”选定。此外,HotSpot虚拟机在安全点的基础上还增加了安全区域的概念,安全区域是安全点的扩展。在一段安全区域中能够实现安全点不能达成的效果。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值