ad

《深入理解 Java 虚拟机 JVM 高级特性与最佳实践(第3版)》_求知之路漫漫_3.4.3 安全区域

网友投稿 124 2023-11-07

【摘要】 本书摘自《深入理解 Java 虚拟机 JVM 高级特性与最佳实践(第3版)》一书中第3章,第4节,周志明著。

3.4.3 安全区域

使用安全点的设计似乎已经完美解决如何停顿用户线程,让虚拟机进入垃圾回收状态 的问题了,但实际情况却并不一定。安全点机制保证了程序执行时,在不太长的时间内就 会遇到可进入垃圾收集过程的安全点。但是,程序“不执行”的时候呢?所谓的程序不执 行就是没有分配处理器时间,典型的场景便是用户线程处于Sleep 状态或者 Blocked 状态, 这时候线程无法响应虚拟机的中断请求,不能再走到安全的地方去中断挂起自己,虚拟机 也显然不可能持续等待线程重新被激活分配处理器时间。对于这种情况,就必须引入安全 区域 (Safe Region) 来解决。

安全区域是指能够确保在某一段代码片段之中,引用关系不会发生变化,因此,在这 个区域中任意地方开始垃圾收集都是安全的。我们也可以把安全区域看作被扩展拉伸了的安 全点。

《深入理解 Java 虚拟机 JVM 高级特性与最佳实践(第3版)》_求知之路漫漫_3.4.3 安全区域

当用户线程执行到安全区域里面的代码时,首先会标识自己已经进入了安全区域,那 样当这段时间里虚拟机要发起垃圾收集时就不必去管这些已声明自己在安全区域内的线程 了。当线程要离开安全区域时,它要检查虚拟机是否已经完成了根节点枚举(或者垃圾收集 过程中其他需要暂停用户线程的阶段),如果完成了,那线程就当作没事发生过,继续执行; 否则它就必须一直等待,直到收到可以离开安全区域的信号为止。

3.4.4 记忆集与卡表

讲解分代收集理论的时候,提到了为解决对象跨代引用所带来的问题,垃圾收集器在 新生代中建立了名为记忆集 (Remembered Set) 的数据结构,用以避免把整个老年代加进 GC Roots扫描范围。事实上并不只是新生代、老年代之间才有跨代引用的问题,所有涉及 部分区域收集 (PartialGC) 行为的垃圾收集器,典型的如G1 、ZGC 和 Shenandoah 收集器, 都会面临相同的问题,因此我们有必要进一步理清记忆集的原理和实现方式,以便在后续 章节里介绍几款最新的收集器相关知识时能更好地理解。

记忆集是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。如果 我们不考虑效率和成本的话,最简单的实现可以用非收集区域中所有含跨代引用的对象数 组来实现这个数据结构,如代码清单3-5 所示:

这种记录全部含跨代引用对象的实现方案,无论是空间占用还是维护成本都相当高昂。 而在垃圾收集的场景中,收集器只需要通过记忆集判断出某一块非收集区域是否存在有指 向了收集区域的指针就可以了,并不需要了解这些跨代指针的全部细节。那设计者在实现 记忆集的时候,便可以选择更为粗犷的记录粒度来节省记忆集的存储和维护成本,下面列 举了一些可供选择(当然也可以选择这个范围以外的)的记录精度:

口字长精度:每个记录精确到一个机器字长(就是处理器的寻址位数,如常见的32位 或64位,这个精度决定了机器访问物理内存地址的指针长度),该字包含跨代指针。

口对象精度:每个记录精确到一个对象,该对象里有字段含有跨代指针。 口卡精度:每个记录精确到一块内存区域,该区域内有对象含有跨代指针。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们 18664393530@aliyun.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:《Python学习笔记 从入门到实战》_更了解Python的途径之一_2.3.1 字符编码
下一篇:《Python+3自动化软件发布系统》Django 2实战_了解Python的更好方法_2.2.4 和 Web 搭上关系
相关文章

 发表评论

暂时没有评论,来抢沙发吧~

×