深入理解Java虚拟机之对象存活算法的实现(2)

深入理解Java虚拟机之对象存活算法的实现(2)

    因为HotSpot是准确式GC(前一篇有说),并且是借助OopMap的协助来实现的,
所以就引出了一个问题,导致引用发生变化或者说导致OopMap发生修改的操作可能有
很多,如果每一个指令都生成一个OopMap这根本就不现实,因为如此以来空间成本就
太高了。所以HopSpot并不是为每一条指令都更新一下OopMap的,而是在特定的一些
位置将引用的对象类型信息更新一下,这些位置称之为“安全点”,即程序执行时并非在
所有的地方都可以进行GC,而是要到达“安全点”的时候才可以进行GC,也就是暂停虚
拟机,所以“安全点”的选定就很重要了,如果选的过长,会导致GC的等待时间太长,
如果选择的过短,就会导致运行的负荷较大,毕竟要频繁的进行暂停启动。
    那么选取安全点的特征是什么呢?就是程序是否具有“长时间执行”的特征,什么叫“长
时间执行”呢?就是指程序的指令序列复用,比方说:调用方法、循环调转、异常调转等。
这样的指令就是安全点的选取范围。除此之外如何让程序中的线程暂停下来也是一个问题,
这个时候有两种选择:抢先式中断和主动式中断,抢先式中断就是说不需要线程自己中断,
而由GC发生时,直接对线程进行中断,如果线程中断的地方不在安全点那么就让线程跑到
安全点上,但现在基本没有虚拟机采用抢先式中断。而主动性中断就是在GC需要中断线程
的时候,不是直接对线程进行操作,而是设置一个标志,各个线程在执行的时候会不断的去
轮询这个标志当发现标志为真的时候就要自己挂起,轮询标志的地方就是在安全点和为新对
象分配内存的地方。
    看似使用“安全点”已经解决了这个问题,但是还有一个问题是“安全点”解决不了的,那
就是当线程处于无法响应中断请求的状态怎么办?比方说线程处于sleep或者blocked状态,
这个时候线程是无法自己走到“安全点”去中断挂起,GC也不可能一直等待这些线程去走到
“安全点”,这个时候就引入了“安全区域”这个概念。
    所谓的“安全区域”可以认为是一些相邻的“安全点”的合体,当线程执行到“安全区域”的
时候,会将自己标示为已经进入了“安全区域”,这样一来在发生GC的时候就不需要管这些线
程了,而在线程将要离开“安全区域”的时候会查询GC是否完成或者说枚举根节点是否已经完
成,如果没有完成,就必须等待直到收到可以离开的信号为止。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值