HotSpot虚拟机的算法实现——深入理解Java虚拟机(八)

前言

   看的人越来越多,我也有必要致敬一下“深入Java虚拟机“这本书了,小疯子每天更新的目录是按着这样的节奏来的,内容都是本人经过理解加上所学内容陈述的,有些点为了标准,也会采用作者的原话,头条还是一个大家闲于时间打发的地方,小疯子希望成为一双监督的眼镜,给大家带来一点实质的好书,有时间的当然可以全本阅读,比小疯子写的更详细,内容更复杂一点,我是把一些初学者没必要深入的点简化了,这样学起来更流畅,后面还会有好书推荐吧,希望大家喜欢,有需要原本的可以留邮箱,作者也会每天坚持的,从六月以来面试了好几家大公司了,偶尔也会有一点面经,http://blog.csdn.net/u011958281这是作者的博客,上面会有更多项目经验交流跟源代码,如果喜欢的可以去看看,缺的可以留言,乐于分享,主要是在这里有很多志趣相投的伙伴可以交流,做起事情来也越加觉得有劲,希望大家互相鼓励把!

HotSpot虚拟机的算法实现——深入理解Java虚拟机(八)

正文

1.枚举根节点

主要谈论之前提到GC Roots如果通着这种方式寻找到所有存活于死亡的对象,常见的叫法是可达性分析法,但是因为现在应用越来越大,要逐个检查定位这些引用,耗费的时间也会相对延长。

同时,可达性分析在执行时,是需要将其他程序停掉的,因为这项分析工作必须在一个能确保一致性的快照中进行——这里“一致性”的意思是指在整个分析期间整个执行系统看起来就像被冻结在某个时间点上,不可以出现分析过程中对象引用关系还在不断变化的情况,该点不满足的话分析结果准确性就无法得到保证。 这点是导致GC进行时必须停顿所有Java执行线程(Sun将这件事情称为“Stop The World”)的其中一个重要原因,即使是在号称(几乎)不会发生停顿的CMS收集器中,枚举根节点时也是必须要停顿的。

目前的主流Java虚拟机使用的都是准确式GC,所以当执行系统停顿下来后,并不需要一个不漏地检查完所有执行上下文和全局的引用位置,虚拟机应当是有办法直接得知哪些地方存放着对象引用。 在HotSpot的实现中,是使用一组称为OopMap的数据结构来达到这个目的的,在类加载完成的时候,HotSpot就把对象内什么偏移量上是什么类型的数据计算出来,在JIT编译过程中,也会在特定的位置记录下栈和寄存器中哪些位置是引用。 这样,GC在扫描时就可以直接得知这些信息了。

2. 安全点

额外存放对象引用OopMap是需要分配内存的,随着对象的引用关系不断复杂,内存也变得越来越大,这样的OopMap对于GC来说,提高的效率就不明显了。所以,并不是每条指令都生成了OopMap,只是在“特定的位置”记录了这些信息,这些位置称为安全点(Safepoint),即程序执行时并非在所有地方都能停顿下来开始GC,只有在到达安全点时才能暂停。 Safepoint的选定既不能太少以致于让GC等待时间太长,也不能过于频繁以致于过分增大运行时的负荷。

另一个需要考虑的问题是如何在GC发生时让所有线程(这里不包括执行JNI调用的线程)都“跑”到最近的安全点上再停顿下来。 这里有两种方案可供选择:抢先式中断(Preemptive Suspension)和主动式中断(Voluntary Suspension),其中抢先式中断不需要线程的执行代码主动去配合,在GC发生时,首先把所有线程全部中断,如果发现有线程中断的地方不在安全点上,就恢复线程,让它“跑”到安全点上。 现在几乎没有虚拟机实现采用抢先式中断来暂停线程从而响应GC事件。

主动式中断的思想是当GC需要中断线程的时候,不直接对线程操作,仅仅简单地设置一个标志,各个线程执行时主动去轮询这个标志,发现中断标志为真时就自己中断挂起。

3.安全区域

安全区域是扩展了的安全点,也就是整块区域都是安全的,可以执行GC,为什么要这么做,主要是考虑到执行的程序在不太长的时间就会遇到安全点,进入GC,但是程序不执行是呢,比如遇到sleep,block状态,它就无法响应JVN中断。

安全区域是指在一段代码片段之中,引用关系不会发生变化。 在这个区域中的任意地方开始GC都是安全的。

在线程执行到Safe Region中的代码时,首先标识自己已经进入了Safe Region,那样,当在这段时间里JVM要发起GC时,就不用管标识自己为Safe Region状态的线程了。 在线程要离开Safe Region时,它要检查系统是否已经完成了根节点枚举(或者是整个GC过程),如果完成了,那线程就继续执行,否则它就必须等待直到收到可以安全离开Safe Region的信号为止。

这节内容相对枯燥,我也是看了好久,主要涉及的知识比较深,也是我们在其他书看不到的,小疯子拿来也是希望大家看后有一个概念,如果面试提起,或者你记住了,可以给自己加分的。

下一节谈几种垃圾收集器,Java语言发展这么久也历经了好几代收集器的演化了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值