随笔 - 361,  文章 - 0,  评论 - 62,  阅读 - 160万

1.枚举根节点

  在可达性分析中,可以作为GC Roots的节点有很多,但是现在很多应用仅仅方法区就有上百MB,如果逐个检查的话,效率就会变得不可接受。

  而且,可达性分析必须在一个一致性的快照中进行-即整个分析期间,系统就像冻结了一样。否则如果一边分析,系统一边动态表化,得到的结果就没有准确性。这就导致了系统GC时必须停顿所有的Java执行线程。

  目前主流Java虚拟机使用的都是准确式GC,所以当执行系统都停顿下来之后,并不需要一个不漏的检查完所有执行上下文和全局的引用位置,虚拟机应该有办法直接知道哪些地方存放着对象引用。在HotSpot实现中,使用一组称为 OopMap 的数据结构来达到这个目的。OopMap会在类加载完成的时候,记录对象内什么偏移量上是什么类型的数据,在JTI编译过程中,也会在特定的位置记录下栈和寄存器哪些位置是引用。这样,在GC扫描的时候就可以直接得到这些信息了。

2.安全点

  如果OopMap内容变化的指令非常多,HotSpot并不会为每条指令都产生OopMap,只是在特定的位置记录了这些信息,这些位置成为“安全点”(SafePoint)。程序执行时只有在达到安全点的时候才停顿开始GC。一般具有较长运行时间的指令才能被选为安全点,如方法调用、循环跳转、异常跳转等。

  接下来要考虑的便是,如何在GC时保证所有的线程都“跑”到安全点上停顿下来。这里有两种方案: 抢先式中断 (Preemptive Suspension) 和主动式中断 (Voluntary Suspension)。

  抢先式中断会把所有线程中断,如果某个线程不在安全点上,就恢复线程让它跑到安全点上。几乎没有虚拟机采用这种方式。

  主动式中断思想是需要中断线程时,不直接对线程操作,而是设置一个GC标志,各个线程会轮询这个标志并在需要时自己中断挂起。这样,轮询标志的地方和安全点是重合的。

3.安全区域

  安全点机制保证程序执行时,在不太长的时间内就会遇到可进入GC的安全点,但是,程序“不执行”的时候呢,程序不执行就是没有分配CPU时间,这时线程无法响应JVM的中断请求,JVM显然不太可能的等待线程重新被分配CPU时间。

  安全区域是指一段代码片段之中,引用关系不会发生变化。在这个区域中的任意地方开始GC都是安全的。

  在线程执行到安全区域代码时,首先标识自己进入安全区域,当这段时间里JVM发起GC,不用管标识为安全区域的线程了。在线程要离开安全区域时,要检查系统是否已经完成了根节点枚举,如果完成,线程继续执行,否则等待直到收到可以安全离开安全区域的信号为止。

posted on   kosamino  阅读(1009)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示