登录

java - Full Gc过程会发生stop the world,这里jvm是怎么处理的呢?【面试题】

在不采用cms垃圾收集器或者在cms垃圾收集器初始标记和重新标记阶段,都会发生stop the world,也就是会暂停用户线程的执行,jvm是如何暂停所有用户线程的?烦请知道的朋友帮忙解答一下~
在实际场景中,可能gc的时间很短,但是暂停所有用户线程会用去很大一部分时间,这个时间又是如何得知的呢?

# Java
迷茫迷茫2189 天前651 次浏览

全部回复(4) 我要回复

  • PHP中文网

    PHP中文网2017-04-18 10:07:31

    JVM有个叫做“安全点”和“安全区域”的东西,在发生GC时,所有的线程都会执行到“安全点”停下来。
    在需要GC的时候,JVM会设置一个标志,当线程执行到安全点的时候会轮询检测这个标志,如果发现需要GC,则线程会自己挂起,直到GC结束才恢复运行。

    还有另一种策略是在GC发生时,直接把所有线程都挂起,然后检测所有线程是否都在安全点,如果不在安全点则恢复线程的执行,等执行到安全点再挂起。

    但是对于一些没有获得或无法获得CPU时间的线程,就没办法等到它执行到安全点了,所以这个时候只要这个线程是在安全区域的,也可以进行GC,安全区域是一段代码段,在这段代码段中对象的引用关系不会发生变化,所以这个时候进行GC也是安全的。

    回复
    0
  • PHP中文网

    PHP中文网2017-04-18 10:07:31

    安全暂停线程的Java方法不太稳定,我觉得Full GC时应该使用的是native方法。
    拿个关注学习一下。。

    回复
    0
  • 怪我咯

    怪我咯2017-04-18 10:07:31

    尽量避免出现full gc,减少使用大数组。

    回复
    0
  • 迷茫

    迷茫2017-04-18 10:07:31

    gc不会很频繁,只会在内存不足时发生(当然也不是绝对的),所以进行stop the world不会很频繁,这保证了不会很影响用户线程,而用户线程都有一个安全区,stop the world就需要等待所有的线程都在安全区内,有可能出现有些很长时间的操作会等很久才能到达安全区,这导致stop the world可能会比gc本身等待的时间还要长,而解决这个问题的办法就是安全区的设定上要合理,比如循环内部可以暂停和循环做完才可以暂停就会有很大差异。而安全区具体怎么设定,就要看jvm厂商的决策了

    回复
    0
  • 取消回复发送