HotSpot 对象存活判定、垃圾回收算法

在进行全局性的垃圾回收时,JVM为保持一致性,Stop The World ,(原因在JVM性能调优已经提到过,为了防止在某个链条上新产生的垃圾对象永远无法被发现)。

枚举根节点

当发生STW停下来之后,JVM并不需要检查所有的引用位置,只需要知道哪里存着这些对象,所以就有了OopMap数据结构存储位置

安全点

OopMap内容变化的指令很多,不能为每一条指令都生成对应的OopMap,HotSpot虚拟机是在特定位置生成了OopMap,这些位置叫做“安全点”。程序执行时只有到了安全点才会暂停下来开始GC。一般具有“长时间执行”这个特点的指令(例如方法调用、循环跳转、异常跳转)才会产生安全点。
如何在GC时让所有线程都跑到安全点上再停顿下来?两种方案:

(1) 抢先式中断。(现在几乎没有虚拟机采用该方法)

不需要线程主动配合,在GC发生的时候就让所有线程都中断,如果发现哪个线程中断的地方不在安全点上,那么就恢复线程,然后让它跑到安全点上。

(2) 主动式中断

GC在需要中断线程的时候不直接对线程操作,设置一个标志,让各个线程主动轮询这个标志,如果中断标志位真时就让自己中断。

安全区域

一段代码片段中引用关系不会改变,在这个区域任意位置GC都是安全的

安全点完美的解决了如何进入GC问题,实际情况可能比这个更复杂,但是如果程序长时间不执行,比如线程调用的sleep方法,这时候程序无法响应JVM中断请求这时候线程无法到达安全点,显然JVM也不可能等待程序唤醒,这时候就需要安全区域了。

安全区域是指一段代码片中,引用关系不会发生变化,在这个区域任何地方GC都是安全的,安全区域可以看做是安全点的一个扩展。线程执行到安全区域的代码时,首先标识自己进入了安全区域,这样GC时就不用管进入安全区域的线层了,线层要离开安全区域时就检查JVM是否完成了GC
Roots枚举,如果完成就继续执行,如果没有完成就等待直到收到可以安全离开的信号。

发布了45 篇原创文章 · 获赞 14 · 访问量 2467

猜你喜欢

转载自blog.csdn.net/qq_44357371/article/details/103834637