垃圾收集与分配策略——(三)HotSpot的算法实现
来源:互联网 发布:四方麻将 河南软件 编辑:程序博客网 时间:2024/05/29 00:30
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
阅读全文
0 0
- 垃圾收集与分配策略——(三)HotSpot的算法实现
- 垃圾收集器与内存分配策略——对象的生命、垃圾收集算法
- 垃圾收集与分配策略——(二)垃圾收集算法
- HotSpot的垃圾收集算法实现
- JVM学习系列(三)——垃圾收集器与内存分配策略
- 垃圾收集算法与内存分配策略
- 垃圾收集器与内存分配策略(三)
- 垃圾收集与分配策略——(五)内存分配与回收策略
- 垃圾收集与分配策略——(四)垃圾收集器
- 浅谈JVM(三)——HotSpot垃圾收集器
- JAVA——垃圾收集器与内存分配策略
- JVM——垃圾收集器与内存分配策略
- JVM学习笔记——垃圾收集器与内存分配策略(1)
- JVM学习笔记——垃圾收集器与内存分配策略(2)
- JVM学习笔记(2)——垃圾收集器与内存分配策略
- 垃圾收集器与内存分配策略——(一)对象已死吗?
- jdk源码分析(四)——垃圾收集器与内存分配策略
- 深入理解java虚拟机读书笔记(三)垃圾收集器与内存分配策略
- vuejs组件之slot内容分发实例详解
- 5. Longest Palindromic Substring
- BZOJ 2210: Pku1379 Run Away 模拟退火
- 杭电1001 Sum Problem
- 算法笔记:使用栈实现汉诺塔(Hanoi)经典算法
- 垃圾收集与分配策略——(三)HotSpot的算法实现
- Java注解
- QWT的配置和使用(1)
- java递归浅析合并排序
- 杭电1002 A + B Problem II
- 机器学习之旅:数据预处理的对象-数据
- C++常成员函数和常对象、对象指针和对象引用
- C++11基础-----std::function & std::bind
- 内存中的堆和栈