HotSpot GC 具体实现关键点概要
GC roots 枚举过程
枚举过程的困难点:
- 范围大: GC roots主要在全局性的引用(常量与静态变量)和执行上下文(如栈帧中的本地变量表)。现在程序仅仅就方法区而言就很大,程序整体体积更是不用说。如果要注意检查这些引用,如查看所有栈帧中的本地变量表,那么时间上肯定是无法接受的。
- 必须在快照中进行:在枚举过程中,不能出现程序运行。因为这会导致GC roots不断变化,造成统计不准确的情况。
- 时间要求高:由于分析必须停止程序的运行,因此时间必须要短
准确式GC
HotSpot采用了准确式GC以提升GC roots的枚举速度。所谓准确式GC,就是让JVM知道内存中某位置数据的类型什么。比如当前内存位置中的数据究竟是一个整型变量还是一个引用类型。这样JVM可以很快确定所有引用类型的位置,从而更有针对性的进行GC roots枚举。
OopMap
HotSpot是利用OopMap(Ordinary Object Pointer Map)来实现准确式GC的。当类加载完成后,HotSpot 就将对象内存布局之中什么偏移量上数值是一个什么样的类型的数据这些信息存放到 OopMap 中;在 HotSpot 的 JIT 编译过程中,同样会插入相关指令来标明哪些位置存放的是对象引用等,这样在 GC 发生时,HotSpot 就可以直接扫描 OopMap 来获取对象引用的存储位置,从而进行 GC Roots 枚举。