这是我参与8月更文挑战的第7天
本篇以HotSpot虚拟机为例,介绍其在实现垃圾回收算法中遇到的问题细节、处理方法。
根结点枚举
什么叫根结点枚举?
在前面介绍垃圾回收算法过程中,主流垃圾收集器皆使用可达性分析算法,从GC Roots集合找引用链,尽管目标明确(节点为全局性的引用),但将所有的引用检查肯定得消耗不少的时间。参照《深入理解Java虚拟机》,所有的收集器在根结点枚举这一步骤都是必须暂停用户线程的。
如何解决线程停顿后重新遍历更节点?
在HotSpot的解决方案里,使用一组称为OopMap的数据结构来解决用户线程停顿、开启,重新遍历根结点的问题。一旦类加载动作完成之后,HotSpot就会把对象内什么偏移量上是什么类型数据计算出来。安全点
什么是安全点?
在OopMap的协助下,HotSpot可以快速的完成GC Roots枚举,但是只是在“特定的位置”记录对象信息,这些位置也被称为“安全点”这些安全点保证了用户程序执行的时候并不少在任何位置都能停下来进行垃圾收集,而是在某个安全的位置才进行垃圾收集。
安全点介绍
在某些代码执行的时候会进入到安全点,例如方法调用、循环跳转、异常跳转
如何在垃圾收集发生时让所有线程都跑到最近的安全点?
抢先式中断: 首先吧所有用户线程全部中断,如果发现用户线程中断的地方不在安全点上,就回复这条线程执行,让他一会再重新中断,直到跑到安全点上。
主动式中断: 设置一个标识位,各个线程执行过程中会不停主动轮询这个标志,一旦发现中断标识为真时在最近的安全点主动中断挂起。
安全区域
当用户线程处于Sleep或者Blocked状态,这时候线程无法相应虚拟机的中断请求,也无法走到最近的安全点主动挂起。
因此需要一个安全区域来解决问题:确保在某一段代码片段中,引用关系不会发生变化,因此,在这个区域中的任何地方进行垃圾收集都是安全的。