垃圾收集与分配策略——(三)HotSpot的算法实现
2017-09-28 23:44
495 查看
HotSpot算法实现
枚举根节点
在可达性分析中,可以作为GC Roots的节点有很多,但是现在很多应用仅仅方法区就有上百MB,如果逐个检查的话,效率就会变得不可接受。
而且,可达性分析必须在一个一致性的快照中进行-即整个分析期间,系统就像冻结了一样。否则如果一边分析,系统一边动态表化,得到的结果就没有准确性。这就导致了系统GC时必须停顿所有的Java执行线程。
目前主流Java虚拟机使用的都是准确式GC,所以当执行系统都停顿下来之后,并不需要一个不漏的检查完所有执行上下文和全局的引用位置,虚拟机应该有办法直接知道哪些地方存放着对象引用。在HotSpot实现中,使用一组称为OopMap的数据结构来达到这个目的。OopMap会在类加载完成的时候,记录对象内什么偏移量上是什么类型的数据,在JTI编译过程中,也会在特定的位置记录下栈和寄存器哪些位置是引用。这样,在GC扫描的时候就可以直接得到这些信息了。
安全点
可能导致引用关系变化,或者说OopMap内容变化的指令非常多,HotSpot并不会为每条指令都产生OopMap,只是在特定的位置记录了这些信息,这些位置成为“安全点”(SafePoint)。程序执行时只有在达到安全点的时候才停顿开始GC。一般具有较长运行时间的指令才能被选为安全点,如方法调用、循环跳转、异常跳转等。
接下来要考虑的便是,如何在GC时保证所有的线程都“跑”到安全点上停顿下来。这里有两种方案:抢先式中断(Preemptive Suspension)和主动式中断(Voluntary Suspension)。
抢先式中断会把所有线程中断,如果某个线程不在安全点上,就恢复让它跑到安全点上。几乎没有虚拟机采用这种方式。
主动式中断思想是设立一个GC标志,各个线程会轮询这个标志并在需要时自己中断挂起。这样,标志和安全点是重合的。
安全区域
Safepoint机制可以保证某一程序在运行的时候,在不长的时间里就可以进入GC的Safepoint。但是如果程序没有分配CPU时间,例如处于Sleep状态或者Blocked状态,这时候线程无法响应JVM的中断请求。对于这种情况,只能用安全区域(Safe Region)来解决。
安全区域是指在一段代码片段之中,引用关系不会发生变化。在这个区域中任意地方开始都是安全的。在线程执行到Safe Region中的代码时,就标记自己已经进入了Safe Region,这样JVM在发起GC时就跳过这些线程。在线程要离开Safe Region时,它要检查系统是否已经完成了枚举(或GC过程),如果完成了线程就继续执行,否则就等待。
参考博客:http://blog.csdn.net/zq602316498/article/details/38750757
枚举根节点
在可达性分析中,可以作为GC Roots的节点有很多,但是现在很多应用仅仅方法区就有上百MB,如果逐个检查的话,效率就会变得不可接受。
而且,可达性分析必须在一个一致性的快照中进行-即整个分析期间,系统就像冻结了一样。否则如果一边分析,系统一边动态表化,得到的结果就没有准确性。这就导致了系统GC时必须停顿所有的Java执行线程。
目前主流Java虚拟机使用的都是准确式GC,所以当执行系统都停顿下来之后,并不需要一个不漏的检查完所有执行上下文和全局的引用位置,虚拟机应该有办法直接知道哪些地方存放着对象引用。在HotSpot实现中,使用一组称为OopMap的数据结构来达到这个目的。OopMap会在类加载完成的时候,记录对象内什么偏移量上是什么类型的数据,在JTI编译过程中,也会在特定的位置记录下栈和寄存器哪些位置是引用。这样,在GC扫描的时候就可以直接得到这些信息了。
安全点
可能导致引用关系变化,或者说OopMap内容变化的指令非常多,HotSpot并不会为每条指令都产生OopMap,只是在特定的位置记录了这些信息,这些位置成为“安全点”(SafePoint)。程序执行时只有在达到安全点的时候才停顿开始GC。一般具有较长运行时间的指令才能被选为安全点,如方法调用、循环跳转、异常跳转等。
接下来要考虑的便是,如何在GC时保证所有的线程都“跑”到安全点上停顿下来。这里有两种方案:抢先式中断(Preemptive Suspension)和主动式中断(Voluntary Suspension)。
抢先式中断会把所有线程中断,如果某个线程不在安全点上,就恢复让它跑到安全点上。几乎没有虚拟机采用这种方式。
主动式中断思想是设立一个GC标志,各个线程会轮询这个标志并在需要时自己中断挂起。这样,标志和安全点是重合的。
安全区域
Safepoint机制可以保证某一程序在运行的时候,在不长的时间里就可以进入GC的Safepoint。但是如果程序没有分配CPU时间,例如处于Sleep状态或者Blocked状态,这时候线程无法响应JVM的中断请求。对于这种情况,只能用安全区域(Safe Region)来解决。
安全区域是指在一段代码片段之中,引用关系不会发生变化。在这个区域中任意地方开始都是安全的。在线程执行到Safe Region中的代码时,就标记自己已经进入了Safe Region,这样JVM在发起GC时就跳过这些线程。在线程要离开Safe Region时,它要检查系统是否已经完成了枚举(或GC过程),如果完成了线程就继续执行,否则就等待。
参考博客:http://blog.csdn.net/zq602316498/article/details/38750757
相关文章推荐
- 垃圾收集器与内存分配策略-HotSpot算法实现
- [jvm解析系列][四]Java的垃圾回收(二)垃圾收集算法,内存分配和回收策略
- 《深入理解java虚拟机》学习笔记05--HotSpot中对象存活判读算法和垃圾收集算法的实现
- 垃圾收集器与内存分配策略_垃圾收集算法
- 对象引用算法、垃圾收集算法、内存分配策略
- 《深入理解 Java 虚拟机》- 笔记 - HotSpot 的垃圾收集算法实现
- Java的垃圾收集算法、垃圾收集器以及内存分配与回收策略
- 【005】【JVM——Hotspot算法实现存活对象判定和垃圾收集】
- 【java基础 8】垃圾收集算法及内存分配策略
- 【java基础 8】垃圾收集算法及内存分配策略
- 深入理解java虚拟机(五):hotspot垃圾收集算法实现
- 深入理解java虚拟机(四)垃圾收集算法及HotSpot实现
- 《JVM学习系列》四.垃圾收集算法及HotSpot的算法实现
- 垃圾收集算法与内存分配策略--《深入理解Java虚拟机》学习笔记
- 垃圾收集器与内存分配策略-垃圾收集算法
- Java虚拟机 垃圾收集算法及HotSpot算法实现
- 垃圾收集器与内存分配策略——对象的生命、垃圾收集算法
- Java虚拟机(二)垃圾收集算法与内存分配策略
- 深入理解java虚拟机(五):hotspot垃圾收集算法实现
- 垃圾收集算法与内存分配策略