zhishiqi15836010823
铜头
采纳率75%
2017-10-29 05:11 阅读 2.0k
已采纳

javaGC回收时,sleep状态并不在安全区域的线程怎么办?还是说线程中断时肯定在安全区域?

深入理解java虚拟机中74,75页讲到安全区域,说到了线程在安全区域的情况,发生GC时,不用管在安全区域的线程,那不在安全区域的线程是什么情况?还是线程中断时,都会停留在安全区域?能提供一下参考资料么

安全区域描述如下
这里忽略了一个问题,当发生GC时,运行中的线程可以跑到Safe Point后进行挂起,而那些处于Sleep或Blocked状态的线程在此时无法响应JVM的中断请求,无法到Safe Point处进行挂起,针对这种情况,可以使用安全区域(Safe Region)进行解决。

Safe Region是指在一段代码片段中,对象的引用关系不会发生变化,在这个区域中的任何位置开始GC都是安全的。
1、当线程运行到Safe Region的代码时,首先标识已经进入了Safe Region,如果这段时间内发生GC,JVM会忽略标识为Safe Region状态的线程;
2、当线程即将离开Safe Region时,会检查JVM是否已经完成GC,如果完成了,则继续运行,否则线程必须等待直到收到可以安全离开Safe Region的信号为止;

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

4条回答 默认 最新

  • 已采纳
    bskfnvjtlyzmv867 等一杯咖啡 2019-01-26 17:27

    提供一篇文章的阐述:https://www.sczyh30.com/posts/Java/jvm-gc-safepoint-condition/
    个人理解觉得安全区域是一个概念,也就是说当线程阻塞睡眠时,其实是可以认为安全的,毕竟线程没有工作,所以不会发生引用变化。用安全区域的概念来说,线程睡眠阻塞其实可以认为它是进入了安全区域,在睡眠阻塞标志了自己已经进入安全区域,那么GC其实可以不用去管这些线程了,就算GC(枚举根节点)的好好的,突然线程想唤醒工作,它发现已经标志了,必须等GC完成工作它才能继续执行。
    粗鄙之见,错误之处,还望指正!

    点赞 4 评论 复制链接分享
  • weixin_44443307 三条欸斯 2020-07-25 21:32

    我觉得不是这样的,如果认为处于sleep状态的线程是安全的话,那么gc过后,对象的位置是会移动的(标记-整理、标记复制)。那么线程局部对象的指针是不是还能正确的指向对象的位置呢。
    还是,这类的情况不会发生。希望能够解答

    点赞 评论 复制链接分享
  • weixin_45467169 教练我想去鹅厂 2020-09-16 15:03

    我也认为阻塞睡眠的时候,线程是在安全区域的,所谓的安全是这个线程在此时间段对象引用等没发生变化,
    它像一个快照一样。上面有人担心地址变化问题,垃圾回收器进行内存空间压缩虽然有可能改变了对象地址,
    但是局部变量表的变量依然可以正确指向新地址的对象,所以不必担心。个人理解欢迎交流。

    点赞 评论 复制链接分享
  • qq_45100518 倾听雪的声音 2021-05-03 17:07

    我是这样认为的:

    1、安全区域是指,离开安全点之后,一直没有改变引用,即OopMap还能用。

    2、睡眠,或是可能阻塞的地方都会生成一个安全点。

    点赞 评论 复制链接分享

相关推荐