美文网首页程序员java进阶干货
一次不必要的GCLocker-initiated young G

一次不必要的GCLocker-initiated young G

作者: 美团Java | 来源:发表于2017-10-24 23:53 被阅读3880次

    简书 占小狼,转载请注明原创出处,谢谢!

    有时在分析GC日志的时候,会看到在一次正常的"Allocation Failure" GC之后,紧跟一次"GCLocker Initiated GC",而且此时年轻代的使用量非常低,大概的GC日志可以看看下面这个。

    可以看到,在发生"GCLocker Initiated GC"时,eden区只使用了1%,毫无疑问,这是一次没有意义的YGC,那为什么会这样呢?

    这得从JNI的GCLocker的相关实现说起,之前文章中已经提过,当使用JNI访问JVM中的字符串时,会使用一对Get/ReleaseStringCritical函数,内部由GCLocker的lock/unlock critical实现,其中unlock critical的实现逻辑如下:

    假设一个场景:
    1、线程T1执行JNI方法,进入critical之后会执行unlock方法,如果它是最后一个离开critical的线程,则会触发一次GC operation(OP1)进行一次GC locker-initiated young gc.
    2、线程T2负责在年轻代申请内存,在申请失败时,会触发一次GC operation(OP2)进行一次 allocation failure young gc.

    因为线程是并发执行的,所以存在以下两种情况:
    1、如果线程T1还没执行到图中的A位置,那么这个时候OP2触发的YGC会被丢弃,这种情况是没有问题的.
    2、如果线程T1执行在A到B的位置,这时_jni_lock_count已经减为0,则GC_Locker::is_active()为false,OP2触发的YGC会被正常的执行,并且会阻塞住OP1触发的YGC,等之前的YGC结束之后,OP1的YGC继续执行,在这种情况,显然是多余的一次。


    其实这是openJDK的一个bug,只是一直没被修复,bug地址

    相关文章

      网友评论

        本文标题:一次不必要的GCLocker-initiated young G

        本文链接:https://www.haomeiwen.com/subject/gkdfpxtx.html