避免长时间gc

关键词

  • 垃圾回收gc
    gc参考:https://blog.csdn.net/xyc1211/article/details/88594745

  • 削峰填谷Peak cut

  • Java的安全点 safepoint
    safepoint是一个记录指令OopMap(指针对象表 ordinary object pointer Map)的位置
    程序执行到了safepoint才能暂停执行, 让gc去回收内存垃圾

  • 可数循环(Counted Loop)、不可数循环(Uncounted Loop) 对safepoint的影响

    可数循环的时候 无法进入safepoint

  • jvm 执行native方法 对safepoint的影响

    执行native 会进入safepoint
    原因:native方法 是 jvm之外的代码。jvm调用外部的代码前,必须记录自身的状态 才能在native方法返回后继续执行,所以必须加入safepoint

背景

jvm虚拟机为了避免 safepoint过多带来过重的负担,有些代码是不给设置safepoint的

例如用int类型索引的for循环: 认为int类型比较小 属于 可数循环(Counted Loop),那循环次数不会很长,就不设置safepoint了

如果在没有safepoint的代码段做了大量耗时的操作,这段时间不会进行GC,一直等到出现了safepoint才会 触发一次长时间的GC,导致程序长时间STW

解决方案

  • 思路:
    对GC 打散运行,削峰填谷,运行多次短 GC,从而避免长GC,防止长时间的垃圾收集

方案1:人工加入safepoint

对于没有safepoint的代码段 ,每隔一段就执行 native 方法,人工触发进入Safepoint

//Thread.sleep(0) 是JNI调用,会进入safepoint
Thread.sleep(0)

方案2:无safepoint代码改为有safepoint的

可数循环(Counted Loop)改为 不可数循环(Uncounted Loop)
就是循环的索引 从 int 修改为 long。

猜你喜欢

转载自blog.csdn.net/xyc1211/article/details/127902867