我是靠谱客的博主 大意洋葱,最近开发中收集的这篇文章主要介绍idea本地跑如何看gc日志_牛逼了!用 IDEA 扒出了开源组件导致FGC的原因关键线索重现问题另辟蹊径解决方案,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

某天上午收到最近发布的一个服务频繁FGC的告警,这个服务只是给公司内部相关人员使用的,并非给互联网用户提供服务的系统。而且功能也比较简单,就是查看一些统计信息、报表数据、数据导出Excel等,访问量非常低。

另外,由于这个服务并不是OLTP,所以就是简单的使用默认的ParallGC垃圾回收器,JVM参数也只是做了简单的配置:

443ec0656a4dfef6fa6fc0aaaf011c4b.png

关键线索

废话不多说,既然有FGC,那就首先查看GC日志。毕竟FGC的原因还是比较多的,GC日志也是最直观的展示FGC原因的证据之一。

这里要补充一句,我们在排查问题时,切记不要靠自己的主观意识猜测,而应该做到每一步的推断都有理有据,这样才能越来越接近真相,找出真正的凶手。

GC日志中寻找FGC的命令以及结果如下所示(只贴出部分):

2b30e134f2849efb7af2ca02ae2ebac2.png

根据这段GC日志就能非常肯定:是因为某些地方调用System.gc()触发的FGC

因为这个服务访问亮比较小,并发量并不高。所以,笔者想看看触发FGC的时候,服务被调用了什么接口(如果是并发很高的OLTP,这种方法可能就不是很适用,毕竟每秒TPS成百上千,甚至更大,根本无法确定是哪个接口引起的)。

以上面这段FGC日志,根据其触发的时间点,然后去系统业务日志中查找。很顺利我们就找到了这个时候是调用了一个导出报表数据到Excel并下载的接口。一开始我还有点怀疑会不会是导出数据量很大引起FGC,但是后面走读业务代码,发现导出数据限制最大不超过1000,所以,这个猜想也就被否定了。

重现问题

既然是导出Excel引起的,那么笔者就打算模拟这段代码,试图以最小量的代码看是否能重现这个问题。毕竟:范围越小,距离真相也就越近

所以,笔者根据这个接口的业务代码,等价的写出了下面这段代码:

3fd4bd1bff3d1447066d220a7ad0e429.png

配套的JVM参数如下,接下来运行这段代码即可。过程是如此顺利,10次Excel操作,10次FGC:

1c15b3424bb90b198506a87dbc4c3aba.png

之所以用这段JVM参数,是为了希望通过-verbose:gc将GC日志直接输出到idea的控制台,而不是将GC日志输出到GC日志文件中,这样更方便定位问题。而且这段JVM参数相比生产环境的JVM参数,堆的大小和比例都是一样的,垃圾回收器也都是默认的。

既然重现问题了,那就相当于问题解决了一半。窃喜,哈哈哈~~~

另辟蹊径

事实上定位这种问题最常见的方法还是借助btrace跟踪是哪里调用了System.gc(),毕竟,如果不能像笔者这种场景用一段很小的代码重现问题,笔者接下来介绍的方法可行性就不是很高。但是既然重现了,那么笔者今天就介绍另外一个门槛更低的办法:借助IDEA强大的搜索功能。毕竟定位问题不是为了炫技,只要能找出问题的办法,都是好办法。

需要说明的,这段代码笔者是在一个新建的Maven工程中运行的,这段代码只依赖了一个jxl。之所以这么做,是为了笔者接下来介绍的方法能更精确的定位问题所在:

11be5ecfe4f8a121840425098e95a567.png

接下来就是笔者介绍的方法:如何通过牛逼的IDEA找出是哪里调用了System.gc()。在搜索触发FGC的元凶之前,需要先下载jxl的源码--这段重现问题源码唯一的Maven依赖。这个下载必不可少,否则IDEA是无法搜到的:

d73a68b4f45a7bd408f9811d263dd3d9.png

jxl源码下载完成后,就是打开IDEA强大的搜索了,由于有些同学是Window,有些同学是Mac,快捷键可能不同。所以笔者不介绍打开这个搜索功能的快捷键,而是介绍打开这个搜索功能的路径:

92541404622f5a128286b361eb0683dc.png

需要再次强调,一定要先通过idea下载jxl的源码,否则 FindinPath是搜不到项目依赖的jxl中的内容。如下图所示,只能搜到jdk源码中哪些地方调用了System.gc():

5eb1977339e0cd27211952868d9874b1.png

如果jxl源码下载后, FindinPath中选择范围 ProjectandLibraries后搜索 System.gc()的结果应该如下所示,红色框中就是依赖的开源组件jxl调用System.gc的地方:

8156863137bcde60bfb3809b7034cf86.png

现在范围就很小很小了,经过代码排查,我们很快就发现是在调用WritableWorkbook的close()方法时调用了System.gc(),从而触发了FGC。

73c9fc84c047dc92edc59170861ab810.png

很多同学可能会想到通过JVM参数-XX:+DisableExplicitGC来屏蔽掉System.gc()的调用,这不是解决问题,而是掩盖问题。而且事实上,这里还有更好的办法,请继续往下看。

解决方案

我们排查jxl中所有调用System.gc()的地方,发现都是下面这种姿势。Bingo,那么我们只需要将workbookSettings中gcDisabled这个字段的值设置为true就不会调用System.gc了:

690da3c05eb65bb434b4f1359594c08d.png

gcDisabled设置为true非常简单,只需要稍微改造一下Workbook.createWorkbook()即可:

5e38562cec808f0c232d99d4dd0fedef.png

代码改造后再次执行,再也不会有调用System.gc触发FGC了。美滋滋呀~~

需要说明的是,最后还需要对这段代码进行压测,不断循环调用,看看是否GC异常,或者有堆外内存泄漏的情况(堆外内存只升不降)。

幸运的是,没有任何问题。开心!

我目前是在职Java开发,如果你现在正在了解Java技术,想要学好Java,渴望成为一名Java开发工程师,在入门学习Java的过程当中缺乏基础的入门视频教程,你可以关注并私信我:01。我这里有一套最新的Java基础JavaSE的精讲视频教程,这套视频教程是我在年初的时候,根据市场技术栈需求录制的,非常的系统完整。

最后

以上就是大意洋葱为你收集整理的idea本地跑如何看gc日志_牛逼了!用 IDEA 扒出了开源组件导致FGC的原因关键线索重现问题另辟蹊径解决方案的全部内容,希望文章能够帮你解决idea本地跑如何看gc日志_牛逼了!用 IDEA 扒出了开源组件导致FGC的原因关键线索重现问题另辟蹊径解决方案所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部