枚举根节点

GC Roots 枚举根节点

描述:GC Roots 被虚拟机用来判断对象是否存活。

一、可以做为GC Roots的对象

位置对象
虚拟机栈栈帧中的本地变量表
本地方法栈JNI(一般指的Native方法)引用的对象
方法区静态属性引用对象
方法区常量引用对象

二、枚举根节点

可达性分析需要考虑下面两个点:

  1. 如果方法区大小就有数百兆,如果逐一检查引用,则肯定消耗性能,所以不可能这么做

  2. 在执行可达性分析时,必须要保证这个过程期间对象的引用关系不能再变化,否则不能保证分析结果正确性

第二点: 必须要停止所有线程去执行枚举根节点,被称为Stop the World

上面两个点反映出来的性能问题,应该如何解决呢?


三、解决方法

  1. OopMap数据解构: 保存GC Roots 节点,避免全局扫描去一一查找。(目前主流java虚拟机都是准确式GC
  2. 安全点: 精简指令,为特定位置(安全点: Safepoint)上的指令生成对应的OopMap,暂停进行GC的位置也是在安全点;
  3. 安全区域 :在一段代码中,引用关系不会发生变化,在这个区域中的任意地方开始GC都是安全的。处理没有被分配CPU时间的线程。

3.1 OopMap会在类加载时进行计算,并在JIT也会进行记录。

安全点设置原则:
1. 不能太少,太少会导致GC等待时间过长
2. 不能太过于频繁,以致于过分增加运行时的负荷

所以安全点的选定基本都是以“是否具有让程序长时间执行的特征”为标准进行选定–因为每条指令执行的时间都非常短暂,程序不太可能因为指令流长度太长这个原因而过长时间运行,“长时间执行” 的最明显特征就是指令程序复用,例如方法调用,循环调转 ,异常跳转等。所以具有这些功能的指令才会产生SafePoint


3.2 GC发生时,让所有线程(不包括执行JNI调用的线程) 都“跑”到最近的安全点上再停顿:

  1. 抢先式中断(Preemptive Suspension) : GC发生时,中断全部线程,如果发现线程不在安全点,则恢复让其”跑” 到安全点
  2. 主动式中断(Voluntary Suspension ): 设置一个标志,然后采用轮询触发。

3.3 安全区域(Safe Region)

主要针对没有分配CPU时间的线程,如线程处于Sleep状态或者Blocked状态。这个时候线程无法响应JVM的中断请求。所以需要安全区域来解决。


参考

  • 《深入理解java虚拟机》
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值