如何阅读GC日志

Demo

without evacuation (partially stw)
1.416: [GC pause (young) (initial-mark), 0.62417980 secs]                    // initial mark phase…....2.042: [GC concurrent-root-region-scan-start]                                // concurrent scan phase start2.067: [GC concurrent-root-region-scan-end, 0.0251507]                       // concurrent scan phase end2.068: [GC concurrent-mark-start]                                            // concurrent mark phase start3.198: [GC concurrent-mark-reset-for-overflow]                               //   well, some awkward exception occurred and would be self-adjusted soon4.053: [GC concurrent-mark-end, 1.9849672 sec]                               // concurrent mark phase end4.055: [GC remark 4.055: [GC ref-proc, 0.0000254 secs], 0.0030184 secs]      // remark phase done, stw[Times: user=0.00 sys=0.00, real=0.00 secs]                           4.088: [GC cleanup 117M->106M(138M), 0.0015198 secs]                         // cleanup phase done, stw[Times: user=0.00 sys=0.00, real=0.00 secs]4.090: [GC concurrent-cleanup-start]                                         // concurrently free up regions that is empty, start4.091: [GC concurrent-cleanup-end, 0.0002721]                                // concurrently free up regions that is empty, end

with evacuation (completely stw)
0.522: [GC pause (young), 0.15877971 secs]                                     // 这是一次ygc// 开始时间点0.522,stw持续时间0.15877971[Parallel Time: 157.1 ms]                                                   //   本次ygc的并行时间157.1ms[GC Worker Start (ms):  522.1  522.2  522.2  522.2                       //     4个GCWorker的启动时间Avg: 522.2, Min: 522.1, Max: 522.2, Diff:   0.1]                        //       平均值,最小值,最大值,最大最小差[Ext Root Scanning (ms):  1.6  1.5  1.6  1.9                             //     4个GCWorker扫描根的时长Avg:   1.7, Min:   1.5, Max:   1.9, Diff:   0.4]                        //       平均值,最小值,最大值,最大最小差[Update RS (ms):  38.7  38.8  50.6  37.3                                 //     4个GCWorkrer更新RS的时长Avg:  41.3, Min:  37.3, Max:  50.6, Diff:  13.3]                        //       平均值,最小值,最大值,最大最小差[Processed Buffers : 2 2 3 2                                          //     4个GCWorker更新的RS数量Sum: 9, Avg: 2, Min: 2, Max: 3, Diff: 1]                             //       总数,平均值,最小值,最大值,最大最小差[Scan RS (ms):  9.9  9.7  0.0  9.7                                       //     4个GCWorker扫描RS的时长Avg:   7.3, Min:   0.0, Max:   9.9, Diff:   9.9]                        //       平均值,最小值,最大值,最大最小差[Object Copy (ms):  106.7  106.8  104.6  107.9                           //     4个GCWorker复制存活对象的时长Avg: 106.5, Min: 104.6, Max: 107.9, Diff:   3.3]                        //       平均值,最小值,最大值,最大最小差[Termination (ms):  0.0  0.0  0.0  0.0                                   //     4个GCWorker的终止时长Avg:   0.0, Min:   0.0, Max:   0.0, Diff:   0.0]                        //       平均值,最小值,最大值,最大最小差[Termination Attempts : 1 4 4 6                                       //     4个GCWorker的尝试终止次数Sum: 15, Avg: 3, Min: 1, Max: 6, Diff: 5]                            //       总数,平均值,最小值,最大值,最大最小差[GC Worker End (ms):  679.1  679.1  679.1  679.1                         //     4个GCWorker的停止时间Avg: 679.1, Min: 679.1, Max: 679.1, Diff:   0.1]                        //       平均值,最小值,最大值,最大最小差[GC Worker (ms):  156.9  157.0  156.9  156.9                             //     4个GCWorker的存活时间Avg: 156.9, Min: 156.9, Max: 157.0, Diff:   0.1]                        //       平均值,最小值,最大值,最大最小差[GC Worker Other (ms):  0.3  0.3  0.3  0.3                               //     4个GCWorker花费在其他杂事上的时间Avg:   0.3, Min:   0.3, Max:   0.3, Diff:   0.0]                        //       平均值,最小值,最大值,最大最小差[Clear CT:   0.1 ms]                                                        //   清除卡表的时长,本阶段串行执行[Other:   1.5 ms]                                                           //   花费在其他时间上事情上的时间,本阶段串行执行[Choose CSet:   0.0 ms]                                                  //     为回收集选择区域的时间[Ref Proc:   0.3 ms]                                                     //     处理对象引用的时间[Ref Enq:   0.0 ms]                                                      //     对象引用入队时间[Free CSet:   0.3 ms]                                                    //     释放回收集的时间[Eden: 12M(12M)->0B(10M) Survivors: 0B->2048K Heap: 13M(64M)->9739K(64M)]   //   回收效果//   Eden从12M回收到0B,容量从12M减少到10M//   Survivors从0B增加到2048K//   堆从13M减少到9739K,容量保持不变[Times: user=0.59 sys=0.02, real=0.16 secs]

参考资料

权威参考
https://blogs.oracle.com/poonam/understanding-g1-gc-logs

性能优化

概述

业务表征点
  • 请求量
  • 响应时间
  • 数据量
系统表征点
  • CPU负载
  • 内存压力
  • IO压力:网络,硬盘
  • 存储压力:数据库,缓存
  • 中间件压力:消息队列
  • Java:JVM
第三表征点
  • 系统监控/报警
  • 系统日志

排查方式

排查思路
  • 最核心的系统/接口是什么?
  • 过去一段时间,bug/故障最多的地方是哪里?
  • 门店数/订单量/…翻2/5/10倍之后,最先支撑不住的点在哪里?
排查流程
  • 排查范围/排查点
  • 排查&发现问题
  • 确定问题的影响范围并按优先级排序
  • 逐一解决问题
先思考,再动手
  • 切忌手太快,发现一个解决一个。但解决的未必是重要问题
  • 切忌排查不全面,贸然动手引起联锁反应
思考全面,方案全面
  • 灰度策略,回滚策略,分支策略,要全面
逻辑和数据
  • 逻辑上是好方案
  • 数据上(预评估和后评估)是好结果
  • 不断分析badcase迭代优化

JVM学习路径

背景知识

  • 我希望你必须具备下面的背景知识,再开始jvm的旅程
java相关
书单备注
java基础默认需要你有java背景相关知识,熟练掌握java常规语法
thinking in java没啥说的,必读
core java和thinking in java二选一吧不过这些java砖头书里面很多内容对互联网来说真没啥用
effective java没啥说的,必读
java concurrency in practice没啥说的,必读
  
周边知识
书单备注
计算机组成原理非特定,任意相关类型书籍
数据结构非特定,任意相关类型书籍
算法非特定,任意相关类型书籍
操作系统非特定,任意相关类型书籍对于java应用程序来说,jvm可以认为是一层操作系统 
设计模式非特定,任意相关类型书籍推荐gof,head first等比较经典的书籍
  

0.0 入门中的入门

书单备注
深入理解JVM,周志明入门中的入门,这本书里的东西都是最最基础的如果这本书能勾起你对JVM进一步的兴趣,继续
JVM规范必读,在学习阶段读个2-3遍都不过分JVM的原理和最终的解释都在这里
Java语言规范必读,在学习阶段读个2-3遍都不过分Java语言的原理和最终的解释都在这里注意:JVM和Java语言两个规范在细节中是不完全一致的,想想看为什么?
  

0.1 补充知识

  • 如果你还希望坚持,说明你对JVM抱有一定的兴趣。继续的学习需要更深入的背景知识
书单备注
虚拟机 – 系统与进程的通用平台https://book.douban.com/subject/3611865/了解虚拟机的定义和发展
编译原理https://book.douban.com/subject/3296317/对编译优化感兴趣的话,必读
C/C++语言知识大型JVM一般都使用C++编写有些小型JVM也能做到纯C编写,不容易(题外话:写惯了OO的代码,看到这种尽量模仿OO的过程式的代码,真心不习惯。另外在CSDN上看到有人开了一门课,叫做用C语言构建大规模OO系统,我也是服)
汇编语言知识所有JVM的底层都离不开汇编,需要了解
深入理解计算机系统https://book.douban.com/subject/26912767/对计算机系统有一个全面的认识
  

0.2 深入学习

书单备注
oracle/sun关于hotspot的在线文档很经典
Oracle JRockithttps://book.douban.com/subject/4873919/三大虚拟机中的另一个
IBM关于J9的在线文档三大虚拟机中的最后一个
R神领衔的国内JVM社区http://hllvm.group.iteye.com/这几年随着iteye的没落也没落了
R神自己关于JVM的帖子http://rednaxelafx.iteye.com/blog/362738比较杂,不建议新人阅读
R神自己推荐的书籍http://rednaxelafx.iteye.com/blog/1886170比我列的强太多太多了
Shenandoah设计原理https://wiki.openjdk.java.net/display/shenandoah/Main号称是下一代的GC,设计比较先进不过这两年的开发进度缓慢,和死了区别不大
Zing设计原理https://www.azul.com/products/zing/virtual-machine/设计先进的商用JVM,适用内存至少64G的大型堆内存空间
Gil Tene的JVM讲义http://greenteajug.cn/2015/10/18/understanding-java-garbage-collection/
dalvik/art设计原理作为客户端的jvm,dalvik/art和服务端的jvm在设计和理念上都有不小的区别在我这样的纯粹主义者看来dalvik/art甚至不应该被称为jvm(不符合jvm规范)不过在学习方面,dalvik/art为我们提供了一个很有意思的另样角度
垃圾回收算法手册https://book.douban.com/subject/26740958/对gc算法感兴趣的话,必读
google scholar的论文非常多,筛选是个头疼的问题
  

0.3 源码阅读

  • 我不太推荐在知识储备不丰富的时候直接阅读源码
书单备注
自己动手写Java虚拟机https://book.douban.com/subject/26802084/这本书真的挺好的,浅显易懂,省略了一些比较复杂的细节原书是使用Go语言写Java虚拟机。我自己写的时候使用的是Java,实现难度不大
jamvm非常精简的jamvm,全C语言编写,阅读难度不大(回忆杀:很怀念当年我用jamvm+gnu classpath在arm4/6上面跑java服务的岁月)
其它相关jvm网上开源的小型jvm还有很多,jikes,kvm都是不错的选择
hotspot源码我不太推荐直接读,除非有比较深刻的知识储备
  

0.9 入门结束

  • 到此为止,我可以认为你已经渡过了jvm的入门阶段了,这对于我来说已经是未知领域了,祝好运