为了账号安全,请及时绑定邮箱和手机立即绑定

一次不必要的GCLocker-initiated young GC

标签:
Java

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

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

https://img1.sycdn.imooc.com//5d5e14d500016eb709000644.png

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

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

https://img1.sycdn.imooc.com//5d5e14d700014a1008910521.png

假设一个场景:
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地址



作者:占小狼
链接:https://www.jianshu.com/p/ecc57a81f73c

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消