java gc日志乱码_JVM层GC调优(下)

GC日志格式

本文是JVM层GC调优(上)的后续,在上一篇文章中,我们介绍了JVM的内存结构、常见的垃圾回收算法以及垃圾收集器和不同收集器中的一些GC调优参数。所以通过上文,我们也对GC相关的内容有了一定的了解。

但是光知道一些调优参数是没用的,我们需要能够从GC的日志中去分析可以调优的地方,这样才能使用这些参数去进行相应的调整,所以本小节将介绍一下不同收集器的GC日志格式。

我们这里以Tomcat为例,首先需要在Tomcat的catalina.sh脚本文件中加入打印GC日志的相关参数,如下:

[

参数说明:

· -XX:+PrintGCDetails 打印GC的详细信息

· -XX:+PrintGCTimeStamps、-XX:+PrintGCDateStamps 打印GC的时间

· -Xloggc:$CATALINA_HOME/logs/gc.log 指定GC日志文件所存放的路径

· -XX:+PrintHeapAtGC 在GC发生的前后打印堆信息

· -XX:+PrintTenuringDistribution 打印对象的年龄信息

默认情况下,JDK1.8使用的是Parallel GC,以下是我们设置了参数后,所输出的日志格式片段如下:

{

注:如果默认不是使用Parallel GC的话,可以加上这个参数启用:-XX:+UseParallelGC。我们主要关注GC的详细信息,所以我就截取这一部分进行一个简单的说明:

2018

知道了如何去查看Parallel GC的日志格式后,我们再来看看CMS GC的日志格式。同样的,到catalina.sh中配置启用CMS GC,如下示例:

[

启用CMS GC后,所输出的日志格式片段如下:

{

同样的,我们主要关注GC的详细信息,所以我就截取这一部分进行一个简单的说明:

2018

然后还有老年代的GC信息,以下这个片段是CMS GC特有的日志信息格式,也就是完整的一次Full GC过程:

2018

接下来就是G1的日志格式,G1在JDK1.8后被广泛使用,所以是需要好好了解一下它的日志格式的。同样的,需要先到catalina.sh中配置启用G1,如下示例:

[

启用C1 GC后,所输出的日志格式片段如下,可以看到与之前的的日志格式区别就比较大了,因为G1的垃圾回收过程也比较复杂:

{

同样的,我们主要关注GC的详细信息,所以我就截取这一部分进行一个简单的说明:

2018

我们也知道,G1收集器里还有一个全局并发标记(global concurrent marking)概念,触发时其日志格式如下,与CMS的标记过程有些类似,这里截取出来做一个简单的说明:

2018

... 略 ...

2018

可视化工具分析GC日志

在上一小节中,我们已经了解了常用的几种垃圾收集器的GC日志格式。俗话说:工欲善其事,必先利其器。在进行GC调优之前我们需要先学习如何使用可视化的GC日志分析工具,去分析GC的日志格式,以此来得知该收集器的响应时间和吞吐量是多少,然后才能针对这两个点去进行调优。这里要介绍的工具是:

在线工具:http://gceasy.io/

GCViewer

首先我们来看在线的工具,在浏览器上访问http://gceasy.io/,然后上传一个GC日志文件,我这里上传的是 Parallel GC 收集器的日志文件:

494f3de1c29672c9667bec01637e7912.png

稍等一会后,该工具就可以帮我们分析出如下这些可视化的图表及表格数据:

2911502b581a231e9c26c99389df5965.png

往下拉我们还可以看到交互图:

1eb95561e5a7e78478b33cafb66f386a.png

以及各种GC时的状态信息:

1053187109f664ad857e42f91e319189.png

触发GC的原因也做了一个统计:

011b358198ea153c274e3bf3c8b27a7a.png

在页面的最上端,还可以下载本次分析的结果报告:

d71c0b8fd0c912bb8d29dae81a7b80f5.png

其他类型的垃圾收集器也是类似的,所以这里也不再演示了,毕竟都是图形化操作的,图表数据也很直观,而且在报告中也已经对各个点进行了说明。

所以接下来我们看看GCViewer的使用,这是一款开源的、用Java编写的客户端工具,GitHub地址如下:

https://github.com/chewiebug/GCViewer

下载压缩包即可,下载好后进行解压,使用cmd进入解压后的目录,然后使用maven命令对其进行编译打包:

D:GCViewGCViewer-develop>mvn clean package -Dmaven.test.skip

第一次打包的过程稍微有些慢,打包成功后,可以在target目录下看到一个jar包,双击这个jar包即可运行:

39070dc4d76482dc4339de5c41d9f14b.png

打开后主界面如下:

fec39f8fd72352a2c8a9b8667f9d399f.png

同样的,打开一个GC日志文件,我这里仍然使用Parallel GC的日志文件作为演示:

360fc2bc7a6155ca37b7d806dac0ab49.png

打开后,可以看到一个概览的图表:

dbacbe65158b56f4c2438dda8f9defb2.png

从Summary选项卡中查看吞吐量:

4103f84d6b521d91c079530891e9e456.png

停顿时间则在Pause选项卡里:

8e8dde6b5754db45d3874cc3a6e10177.png

Memory选项卡里自然就是查看内存相关的统计信息了:

c23a724f0c526e88fe8809ff36b9c312.png

查看触发GC的原因在Event Detail选项卡里:

1d1a6e18df0cfabbebcc637e3e362ecd.png

关于GCViewer就介绍到这,详细的说明可以参考官方的文档。

Parallel GC调优

GC调优无外乎以下三个步骤:

打印GC日志

根据日志得到关键性能指标

分析GC原因,调整JVM参数

Parallel GC调优的指导原则:

除非确定,否则不要设置最大堆内存

优先设置吞吐量目标

如果吞吐量目标达不到,调大最大内存,不能让OS使用Swap,如果仍然达不到,降低目标

如果吞吐量能达到,但GC时间太长,则设置停顿时间的目标

现在我们来简单的实战一把GC调优,同样的,还是以Tomcat为例,使用Parallel GC。首先设置一些初始参数:

[

重启Tomcat完成后,把GC日志下载到本地,然后使用上一小节所介绍到的可视化工具进行分析,首先要关注的是吞吐量和停顿时间的数据,在下图中可以看到最大停顿时间有点长:

a8ac85fcbef0b0e4703b81687033085e.png

我们再看看各种GC的状态信息,发现Full GC发生了三次,所以才导致最大停顿时间有点长:

166666397d37c5d79225d97ebc2e2c86.png

然后我们看看触发GC的原因,可以看到是Metaspace区域分配内存失败导致的:

f5a34b5477a39cd7541d5ce761d7ccb2.png

所以就可以得知是Metaspace区域的内存有点小了,仅仅是启动的过程就发生了三次Full GC,那么我们就需要给Metaspace区域调大些内存。其实在页面顶端,该工具也很智能的提示了我们需要调整的地方:

89f24dec630051fb4bc36b146279d23a.png

我这里的Metaspace区域内存大小默认为34M,所以我先给它调到64M看看。调优是一个不断重复尝试的过程,至于需要尝试多少次完全取决于经验和运气了。在之前的初始化参数中,加入如下参数:

[

再次将日志文件上传到可视化工具中进行分析,可以发现最大停顿时间明显变短了:

5bb92a5318822d5bcaabdc4f03226213.png

那么除此之外我们还可以做哪些调优呢?在本小节的开头我们也说了,当使用Parallel GC的时候,我们可以设置吞吐量目标和停顿时间目标,让它去自动进行调整。在之前的参数中,加入如下参数:

[

再次将日志文件上传到可视化工具中进行分析,发现停顿时间变化并不大,吞吐量反而还降低了一些,实际上这点差距是很小的,毕竟这只是一个Tomcat启动过程中的GC日志:

a1da42aa1d55720cb7dad73ac95ce38a.png

但是我们会发现,调整了一些参数后,Full GC的次数是少了,但是Young GC的次数仍然没有降下来,虽然不可以随便修改堆的大小,但我们可以稍微修改动态扩容增量的参数。在之前的参数中,加入如下参数:

[

再次将日志文件上传到可视化工具中进行分析,可以看到,稍微比之前好了那么一些,Young GC比之前减少了两次:

b1af87d8e18c9bb0168d483f6adb23bc.png

关于Parallel GC的调优就先介绍到这,实际上调优都是需要经验来积累的,不是一蹴而就的,所以这里也只是给出一些调优的步骤、方式而已。

G1调优

在上一小节中,我们介绍了Parallel GC的调优,而在本小节中,将介绍一下G1收集器的调优。G1 GC的最佳实践:

年轻代大小:避免使用-Xmn、-XX:NewRatio等显式设置Young区大小,会覆盖暂停时间目标

暂停时间目标:暂停时间不要太严苛,其吞吐量目标是90%的应用程序时间和10%的垃圾回收时间,太严苛会直接影响到吞吐量

同样的,我们先不设置任何调优参数,只是设置一些初始参数,然后再来做对比,也是以Tomcat为例(之前Parallel GC相关的参数要去掉),如下:

[

和之前一样,重启Tomcat完成后,把GC日志下载到本地,然后上传到工具上进行分析,可以看到使用了G1后,停顿时间明显小了很多,但吞吐量变化不大,因为G1是停顿时间优先的收集器:

ffc206d3fc863fbc914d8b4c8759f581.png

从触发GC的原因可以看到,Metaspace区域发生了一次GC,并且Young GC的次数也比较多:

62c57efb03fc33b4b537f8582bee3cc9.png

同样的,在页面顶端,该工具也提示了我们可以调整Metaspace区域的大小:

10c16222bd62a9abf85afa56df43dbfd.png

那我们就和之前一样,调大Metaspace区域看看:

[

再次将日志文件上传到可视化工具中进行分析,可以看到吞吐量上去了一些:

eb4aeb8f87efd4086d1c4cf8395f25a2.png

而且也没有再发生Full GC了:

3de1845e2434a0831bbddaa32295d644.png

但是从上图中可以看到Young GC的次数依然很多,我们可以试着将堆的大小调大一些看看。如下:

[

再次将日志文件上传到可视化工具中进行分析,可以看到吞吐量和停顿时间却变长了一些:

b8d62c63f696805e1f5eead94a72020d.png

但是Young GC的次数明显少了很多:

f625efa7abdb47e0c734ad2ab316fd7f.png

我们都知道G1是停顿时间优先的收集器,所以我们可以设置一个停顿时间目标,让G1自己自动调整去达到这个目标。如下:

[

再次将日志文件上传到可视化工具中进行分析,结果是吞吐量上去了一些,但停顿时间却变长了一些:

23ce5e89c0028b4c1c77dd9099add287.png

因为这个Tomcat里面也没有跑什么实际的应用,所以调优的变化并不是很大,但是也是有那么一些差别的。G1收集器的调优参数无非也就这几个,更多的是要对日志进行分析以及经验的积累,才能得出高效的调优方式。

对标阿里P6+的Java架构师

获取更多学习资料,可以扫描下方二维码。

999d1d944f0aa2e0570098529e7b1091.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值