您的位置:首页 > 编程语言 > Java开发

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

2017-12-19 21:56 375 查看

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

因为HotSpot是准确式GC(前一篇有说),并且是借助OopMap的协助来实现的,

所以就引出了一个问题,导致引用发生变化或者说导致OopMap发生修改的操作可能有

很多,如果每一个指令都生成一个OopMap这根本就不现实,因为如此以来空间成本就

太高了。所以HopSpot并不是为每一条指令都更新一下OopMap的,而是在特定的一些

位置将引用的对象类型信息更新一下,这些位置称之为“安全点”,即程序执行时并非在

所有的地方都可以进行GC,而是要到达“安全点”的时候才可以进行GC,也就是暂停虚

拟机,所以“安全点”的选定就很重要了,如果选的过长,会导致GC的等待时间太长,

如果选择的过短,就会导致运行的负荷较大,毕竟要频繁的进行暂停启动。

那么选取安全点的特征是什么呢?就是程序是否具有“长时间执行”的特征,什么叫“长

时间执行”呢?就是指程序的指令序列复用,比方说:调用方法、循环调转、异常调转等。

这样的指令就是安全点的选取范围。除此之外如何让程序中的线程暂停下来也是一个问题,

这个时候有两种选择:抢先式中断和主动式中断,抢先式中断就是说不需要线程自己中断,

而由GC发生时,直接对线程进行中断,如果线程中断的地方不在安全点那么就让线程跑到

安全点上,但现在基本没有虚拟机采用抢先式中断。而主动性中断就是在GC需要中断线程

的时候,不是直接对线程进行操作,而是设置一个标志,各个线程在执行的时候会不断的去

轮询这个标志当发现标志为真的时候就要自己挂起,轮询标志的地方就是在安全点和为新对

象分配内存的地方。

看似使用“安全点”已经解决了这个问题,但是还有一个问题是“安全点”解决不了的,那

就是当线程处于无法响应中断请求的状态怎么办?比方说线程处于sleep或者blocked状态,

这个时候线程是无法自己走到“安全点”去中断挂起,GC也不可能一直等待这些线程去走到

“安全点”,这个时候就引入了“安全区域”这个概念。

所谓的“安全区域”可以认为是一些相邻的“安全点”的合体,当线程执行到“安全区域”的

时候,会将自己标示为已经进入了“安全区域”,这样一来在发生GC的时候就不需要管这些线

程了,而在线程将要离开“安全区域”的时候会查询GC是否完成或者说枚举根节点是否已经完

成,如果没有完成,就必须等待直到收到可以离开的信号为止。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: