一次不必要的GCLocker-initiated young GC

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

有时在分析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地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • System.gc整理 System.gc()源码public static void gc() { Runtim...
    andersonoy阅读 2,967评论 0 1
  • 简书 占小狼转载请注明原创出处,谢谢! GC locker是什么? 概念太抽象,一两句话说不清... 先看看它被使...
    美团Java阅读 8,720评论 7 22
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,740评论 18 399
  • 作者:一字马胡 转载标志 【2017-11-12】 更新日志 日期更新内容备注 2017-11-12新建文章初版 ...
    beneke阅读 2,231评论 0 7
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,726评论 0 11