JVM系列(5)-HotSpot 1

问题1:HotSpot是什么东东?


JVM制定了一个规范,不同的公司或者个人可以根据规范实现自己的Java虚拟机。为了便于理解可以将规范理解为接口,接口可以简化理解为一个方法,定义应该具有哪些功能。


例如swap(a,b) 意思就是交换a和b的值。至于方法的实现不关心,最终能把a,b值交换过来就成,这就是规范。不管黑猫还是白猫,能逮着老鼠就行。


HotSpot就是JVM规范的一个实现,也是最流行的一个虚拟机实现。除了HotSpot还有JRockit、J9 VM等。


问题2:Stop the world


先回忆下判断对象是否可以回收有哪些方法。

答案:引用计数和可达性分析,因为引用计数在对象之间存在相互引用关系的情况下无效,所以大部分的JVM实现都是采用可达性分析算法。

使用可达性分析算法,就需要枚举根节点,然后遍历对象,找到根节点到达不了的对象,也就是可回收的对象。


这里面就有一个问题,在JVM通过根节点遍历对象的时候,允许其他Java线程运行吗?

当然不能,因为可达性有可能会在线程运行过程中发生变化。例如,一个可通过根节点到达的对象,在线程继续运行但还没有开始回收这段时间,变为了不可达,当执行垃圾回收时是应该被回收掉的,但却没有。


所以这就导致GC运行时,必须停顿所有的Java执行线程,也就是Stop the world。


问题3:安全点


我们知道当执行GC时,就需要Stop the world。那什么时候执行GC呢?每运行一条指令就执行一次GC吗?想想也不合情理,就像每走一步就停下来,打打身上的灰尘一样,一公里的路得停多少次,一步距离能集多大点灰尘。合理的做法是先走到一个地点,这个地点呢还很干净,不会让你身上新增灰尘,然后再开始抖灰尘也就是垃圾回收。


这个点就是我们说的安全点,安全点的选取不能过大也不能过小,过大会导致垃圾太多,过小会导致收集太频繁,增加运行时负荷。


这里还有个问题,GC “Stop the world” 的时候怎么保证所有的线程都到了安全点? 

方案1:强先式中断,GC中断时把所有线程都中断,如果发现有线程中断的地方不在安全点上,就恢复它,让它执行到安全点。

// 当下没有哪个虚拟机实现使用这个方案。。。

方案2:主动式中断,GC中断的时候设置一个标志位,各个线程执行的时候,主动轮询这个标志位(轮询标志的地方和安全点重合),发现为真时,就自己中断挂起。


问题4:安全区域


安全区域可以简单的理解为安全点的扩展,也就是在这个区域,引用关系不会发生变化,可以放心的执行GC。


那问什么要引入安全区这个概念呢?

我们知道,在线程sleep或者block的时候,是没法响应虚拟机的中断请求的,可以理解为没法设置执行线程的标志位,导致当线程获取CPU执行时间并轮询时,标志位并没有改变。


当线程进入安全区时,就标记一下,说明自己进入安全区了,这个时候JVM如果要GC是安全的;

当线程离开安全区时,要先检查系统是否已经完成了根节点枚举或者整个GC过程,如果完成了,就可以离开安全区,否则就需要等待。


今天就到这儿,明天继续^_^。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值