文章目录
一:Java命令
作为一个合格的开发人员,不仅要能写好代码,还有一项很重要的技能就是排查问题。这里提到的排查问题不仅仅是在coding的过程中debug等,还包括的就是线上问题的排查。由于在生产环境中,一般没办法debug,所以我们需要借助一些常用命令来查看运行时的具体情况,这些运行时信息包括但不限于运行日志、异常堆栈、堆使用情况、GC情况、JVM参数情况、线程情况等。
那么我们来介绍常用的Java命令,这些命令都是被存放在JDK安装目录的bin目录中,下面来介绍一下相关命令以及具体使用方式
1、jps:显示所有java进程pid
jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,常适合在linux/unix平台上简单察看当前java进程的一些简单情况。
jps类似linux/unix平台上上的ps命令,但是jps只查找查找所有的Java应用程序,包括即使没有使用java执行体的那种(例如,定制的启动器)。另外,jps仅查找当前用户的Java进程,而不是当前系统中的所有进程。
- 学习一个命令,先来看看帮助,使用jps -help查看帮助:
参数介绍:
- -q:只显示pid,不显示class名称,jar文件名和传递给main()方法的参数。
- -m:输出传递给main()方法的参数,在嵌入式jvm上可能是null。
- -l:输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名。
- -v:输出传递给JVM的参数。
常用指令:
- jps:显示当前用户的所有java进程的pid。
- jps -v 3331:显示虚拟机参数。
- jps -m 3331:显示传递给main()函数的参数。
- jps -l 3331:显示主类的全路径。
2、jinfo:实时查看和调整虚拟机参数
主要作用是实时查看和调整虚拟机参数。配置信息包括JAVA系统参数和命令行参数,如果运行在64位虚拟机上运行,需要指定-J-d64参数,如:jinfo -J-d64 -sysprops pid。
由于打印jvm常用信息可以使用Jps命令,并且在后续的java版本中可能不再支持(注:jdk8中已经不支持该命令)。
-
使用jinfo -help查看帮助:
常用指令: -
jinfo -flag CMSIniniatingOccupancyFration 1444:查询CMSIniniatingOccupancyFration参数值。
3、jstat:监控虚拟机各种运行状态信息
jstat(JVM Statistics Monitoring Tool)是用于监控虚拟机各种运行状态信息的命令行工具。他可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形的服务器上,它是运行期定位虚拟机性能问题的首选工具。
- 查看帮助: jstat -help
利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。可见,Jstat是轻量级的、专门针对JVM的工具,非常适用。
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
- 参数解释
Option
:选项,我们一般使用 -gcutil 查看gc情况
vmid
: VM的进程号,即当前运行的java进程号
interval
:间隔时间,单位为秒或者毫秒
count
:打印次数,如果缺省则打印无数次
参数interval
和count
代表查询间隔和次数,如果省略这两个参数,说明只查询一次
假设需要每250毫秒查询一次进程5828垃圾收集状况,一共查询5次,那命令行如下
jstat -gc 5828 250 5
option:
选项option代表这用户希望查询的虚拟机信息,主要分为3类:类装载、垃圾收集和运行期编译状况,具体选项及作用如下:
–class
监视类装载、卸载数量、总空间及类装载所耗费的时间–gc
监视Java堆状况,包括Eden区、2个Survivor区、老年代、永久代等的容量–gccapacity
监视内容与-gc
基本相同,但输出主要关注Java堆各个区域使用到* 的最大和最小空间–gcutil
监视内容与-gc
基本相同,但输出主要关注已使用空间占总空间的百分比–gccause
与-gcutil
功能一样,但是会额外输出导致上一次GC产生的原因–gcnew
监视新生代GC的状况–gcnewcapacity
监视内容与-gcnew
基本相同,输出主要关注使用到的最大和最小空间–gcold
监视老年代GC的状况–gcoldcapacity
监视内容与——gcold基本相同,输出主要关注使用到的最大和最小空间–gcpermcapacity
输出永久代使用到的最大和最小空间–compiler
输出JIT编译器编译过的方法、耗时等信息–printcompilation
输出已经被JIT编译的方法
常用指令:
jstat –class <pid> : 显示加载class的数量,及所占空间等信息
- Loaded 装载的类的数量
- Bytes 装载类所占用的字节数
- Unloaded 卸载类的数量
- Bytes 卸载类的字节数
- Time 装载和卸载类所花费的时间
jstat -compiler <pid>:显示VM实时编译的数量等信息
- Compiled 编译任务执行数量
- Failed 编译任务执行失败数量
- Invalid 编译任务执行失效数量
- Time 编译任务消耗时间
- FailedType 最后一个编译失败任务的类型
- FailedMethod 最后一个编译失败任务所在的类及方法
jstat -gc <pid>:可以显示gc的信息,查看gc的次数,及时间
- S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- EC 年轻代中Eden(伊甸园)的容量 (字节)
- EU 年轻代中Eden(伊甸园)目前已使用空间 (字节)
- OC Old代的容量 (字节)
- OU Old代目前已使用空间 (字节)
- PC Perm(持久代)的容量 (字节)
- PU Perm(持久代)目前已使用空间 (字节)
- YGC 从应用程序启动到采样时年轻代中gc次数
- YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC 从应用程序启动到采样时old代(全gc)gc次数
- FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT 从应用程序启动到采样时gc用的总时间(s)
jstat -gccapacity <pid>:可以显示VM内存中三代(young,old,perm)对象的使用和占用大小
- NGCMN 年轻代(young)中初始化(最小)的大小(字节)
- NGCMX 年轻代(young)的最大容量 (字节)
- NGC 年轻代(young)中当前的容量 (字节)
- S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
- EC 年轻代中Eden(伊甸园)的容量 (字节)
- OGCMN old代中初始化(最小)的大小 (字节)
- OGCMX old代的最大容量(字节)
- OGC old代当前新生成的容量 (字节)
- OC Old代的容量 (字节)
- PGCMN perm代中初始化(最小)的大小 (字节)
- PGCMX perm代的最大容量 (字节)
- PGC perm代当前新生成的容量 (字节)
- PC Perm(持久代)的容量 (字节)
- YGC 从应用程序启动到采样时年轻代中gc次数
- FGC 从应用程序启动到采样时old代(全gc)gc次数
jstat -gcutil <pid>:统计gc信息
- S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比
- S1 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比
- E 年轻代中Eden(伊甸园)已使用的占当前容量百分比
- O old代已使用的占当前容量百分比
- P perm代已使用的占当前容量百分比
- YGC 从应用程序启动到采样时年轻代中gc次数
- YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
- FGC 从应用程序启动到采样时old代(全gc)gc次数
- FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT 从应用程序启动到采样时gc用的总时间(s)
jstat -gcnew <pid>:年轻代对象的信息
- S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
- S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
- S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
- S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
- TT 持有次数限制
- MTT 最大持有次数限制
- EC 年轻代中Eden(伊甸园)的容量 (字节)
- EU 年轻代中Eden(伊甸园)目前已使用空间 (字节)
- YGC 从应用程序启动到采样时年轻代中gc次
- YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
jstat -gcnewcapacity<pid>:年轻代对象的信息及其占用量
- NGCMN 年轻代(young)中初始化(最小)的大小(字节)
- NGCMX 年轻代(young)的最大容量 (字节)
- NGC 年轻代(young)中当前的容量 (字节)
- S0CMX 年轻代中第一个survivor(幸存区)的最大容量 (字节)
- S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
- S1CMX 年轻代中第二个survivor(幸存区)的最大容量 (字节)
- S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
- ECMX 年轻代中Eden(伊甸园)的最大容量 (字节)
- EC 年轻代中Eden(伊甸园)的容量 (字节)
- YGC 从应用程序启动到采样时年轻代中gc次数
- FGC 从应用程序启动到采样时old代(全gc)gc次数
jstat -gcold <pid>:old代对象的信息
- PC Perm(持久代)的容量 (字节)
- PU Perm(持久代)目前已使用空间 (字节)
- OC Old代的容量 (字节)
- OU Old代目前已使用空间 (字节)
- YGC 从应用程序启动到采样时年轻代中gc次数
- FGC 从应用程序启动到采样时old代(全gc)gc次数
- FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT 从应用程序启动到采样时gc用的总时间(s)
stat -gcoldcapacity <pid>: old代对象的信息及其占用量
- OGCMN old代中初始化(最小)的大小 (字节)
- OGCMX old代的最大容量(字节)
- OGC old代当前新生成的容量 (字节)
- OC Old代的容量 (字节)
- YGC 从应用程序启动到采样时年轻代中gc次数
- FGC 从应用程序启动到采样时old代(全gc)gc次数
- FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT 从应用程序启动到采样时gc用的总时间(s)
jstat –gcpermcapacity <pid>: perm对象的信息及其占用量
- PGCMN perm代中初始化(最小)的大小 (字节)
- PGCMX perm代的最大容量 (字节)
- PGC perm代当前新生成的容量 (字节)
- PC Perm(持久代)的容量 (字节)
- YGC 从应用程序启动到采样时年轻代中gc次数
- FGC 从应用程序启动到采样时old代(全gc)gc次数
- FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
- GCT 从应用程序启动到采样时gc用的总时间(s)
jstat -printcompilation <pid>:当前VM执行的信息
- Compiled 编译任务的数目
- Size 方法生成的字节码的大小
- Type 编译类型
- Method 类名和方法名用来标识编译的方法。类名使用/做为一个命名空间分隔符。方法名是给定类中的方法。上述格式是由-XX:+PrintComplation选项进行设置的
4、jmap:生成堆转储快照
jmap是JDK自带的工具软件,主要用于打印指定Java过程(或核心文件,远程调试服务器)的共享对象内存映射或堆内存细节。可以使用jmap生成堆转储。
-
查看帮助:jmap -help
option参数详解: -
<no option>
如果使用不带选项参数的jmap打印共享对象映射,将打印目标虚拟机中加载的每个共享对象的起始地址,映射大小以及共享对象文件的路径全称。 -
-dump:[live,]format=b,file=<filename>
以hprof二进制格式转储Java堆到指定filename的文件中。 live子选项是可选的。如果指定了live子选项,堆中只有活动的对象会被转储。想要浏览堆转储,你可以使用jhat (Java的堆分析工具)读取生成的文件。 -
-finalizerinfo
打印等待终结的对象信息。 -
-heap
打印一个堆的摘要信息,包括使用的GC算法,堆配置信息和代明智堆的使用情况。-histo[:live] 打印堆的柱状图。其中包括每一个Java类,对象数量,内存大小(单位:字节),完全限定的类名。打印的虚拟机内部的类名称将带有一个’*'替换。如果指定了live子选项,则只计算活动的对象。-permstat 打印的Java堆内存的永久保存区域的类加载器的智能统计信息。对于每个类加载器而言,它的名称 活跃度,地址,父类加载器,它所加载的类的数量和大小都会被打印。此外包含的字符串数量和大小也会被打印。 -
-F
强制模式。如果指定的PID没有响应,请使用JMAP -dump或jmap -histo选项。此模式下,不支持live子选项。 -
-h
打印帮助信息。 -
-help
打印帮助信息。 -
-J<flag>
指定传递给运行jmap的JVM的参数。
常用指令:
jmap -heap 31846 查看java堆(heap)使用情况
Attaching to process ID 31846, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.71-b01
using thread-local object allocation.
Parallel GC with 4 thread(s)//GC 方式
Heap Configuration: //堆内存初始化配置
MinHeapFreeRatio = 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
MaxHeapFreeRatio = 100 //对应jvm启动参数-XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
MaxHeapSize = 2082471936 (1986.0MB) //对应启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
NewSize = 1310720 (1.25MB)//对应jvm启动参数-XX:NewSize=设置JVM堆的‘新生代’的默认大小
MaxNewSize = 17592186044415 MB//对应jvm启动参数-XX:MaxNewSize=设置JVM堆的‘新生代’的最大大小
OldSize = 5439488 (5.1875MB)//对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的‘老生代’的大小
NewRatio = 2 //对应jvm启动参数-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
SurvivorRatio = 8 //对应jvm启动参数-XX:SurvivorRatio=设置年轻代中Eden区与Survivor区的大小比值
PermSize = 21757952 (20.75MB) //对应jvm启动参数-XX:PermSize=<value>:设置JVM堆的‘永生代’的初始大小
MaxPermSize = 85983232 (82.0MB)//对应jvm启动参数-XX:MaxPermSize=<value>:设置JVM堆的‘永生代’的最大大小
G1HeapRegionSize = 0 (0.0MB)
Heap Usage://堆内存使用情况
PS Young Generation
Eden Space://Eden区内存分布
capacity = 33030144 (31.5MB)//Eden区总容量
used = 1524040 (1.4534378051757812MB) //Eden区已使用
free = 31506104 (30.04656219482422MB) //Eden区剩余容量
4.614088270399305% used //Eden区使用比率
From Space: //其中一个Survivor区的内存分布
capacity = 5242880 (5.0MB)
used = 0 (0.0MB)
free = 5242880 (5.0MB)
0.0% used
To Space: //另一个Survivor区的内存分布
capacity = 5242880 (5.0MB)
used = 0 (0.0MB)
free = 5242880 (5.0MB)
0.0% used
PS Old Generation //当前的Old区内存分布
capacity = 86507520 (82.5MB)
used = 0 (0.0MB)
free = 86507520 (82.5MB)
0.0% used
PS Perm Generation//当前的“永生代” 内存分布
capacity = 22020096 (21.0MB)
used = 2496528 (2.3808746337890625MB)
free = 19523568 (18.619125366210938MB)
11.337498256138392% used
670 interned Strings occupying 43720 bytes.
jmap -histo 3331:查看堆内存(直方图)中的对象数量及大小。
#num #instances #bytes #class name
编号 个数 字节 类名
----------------------------------------------------------------
1: 7 1322080 [I
2: 5603 722368 <methodKlass>
3: 5603 641944 <constMethodKlass>
4: 34022 544352 java.lang.Integer
5: 371 437208 <constantPoolKlass>
6: 336 270624 <constantPoolCacheKlass>
7: 371 253816 <instanceKlassKlass>
jmap -dump:format=b,file=heapDump 6900 将要使用的内存的详细情况输出到文件
然后用jhat命令可以参见jhat -port 5000 heapDump在浏览器中访问:http://localhost:5000/查看详细信息
这个命令执行,JVM重新整堆堆的信息转储写入一个文件,堆如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证转储的信息是可靠的,所以会暂停应用。
总结:
- 如果程序内存不足或经常GC,很有可能存在内存不足情况,这时候就要重新使用Java堆Dump查看对象的情况
- 要制作堆Dump可以直接使用jvm自带的jmap命令
- 可以先使用
jmap -heap
命令查看堆的使用情况,看一下各个堆空间的占用情况。 - 使用
jmap -histo:[live]
查看堆内存中的对象的情况。如果有大量对象在持续被引用,并没有被释放掉,那就产生了内存泄露,就要结合代码,把不用的对象释放掉。 - 可以使用
jmap -dump:format=b,file=<fileName>
命令将堆信息保存到一个文件中,再借助与jhat命令查看详细内容 - 在内存出现泄露,溢出或者其它前提条件下,建议多转储先前的内存,把内存文件进行编号扩展,并进行后续的内存整理分析。
5、jhat:Java堆分析工具
jhat(Java堆分析工具),是一个用来分析java的堆情况的命令。使用jmap可以生成Java堆的Dump文件。生成转储文件之后就可以用jhat命令,将转储文件转成html的形式,然后通过http访问可以查看堆情况。
jhat命令解析会Java堆dump并启动一个web服务器,然后就可以在浏览器中查看堆的dump文件了。
- 使用 jhat -help 查看帮助
使用步骤: - 1.查看该进程的ID
jps //使用jps命令查看JAVA进程ID
- 2.生成转储文件
jmap -dump:format=b,file=heapDump 62247
- 3.解析Java堆转储文件,并启动一个Web服务器
jhat heapDump
- 使用jhat命令,就启动了一个http服务,端口是7000,然后在访问 http://localhost:7000/,就可以在浏览器中查看堆的dump文件了。
常用命令:
- jmap -dump:format=b,file=heapDump 3331 + jhat heapDump:生成并解析Java堆转储文件,并启动一个 web server
6、jstack:堆栈跟踪工具
jstack是java虚拟机自带的一种堆栈跟踪工具
jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。
拓展知识:
- 线程状态
想要通过jstack命令来分析线程的情况的话,首先要知道线程都有哪些状态,下面这些状态是我们使用jstack命令查看线程堆栈信息时可能会看到的线程的几种状态:
NEW
,未启动的。不会出现在Dump中。
RUNNABLE
,在虚拟机内执行的。 BLOCKED,受阻塞并等待监视器锁。
WATING
,无限期等待另一个线程执行特定操作。
TIMED_WATING
,有时限的等待另一个线程的特定操作。
TERMINATED
,已退出的。
- 调用修饰
表示线程在方法调用时,额外的重要的操作。线程Dump分析的重要信息。修饰上方的方法调用。
locked <地址> 目标:使用synchronized申请对象锁成功,监视器的拥有者。
waiting to lock <地址>目标:使用synchronized申请对象锁未成功,在迚入区等待。 waiting on <地址>目标:使用synchronized申请对象锁成功后,释放锁幵在等待区等待。
parking to wait for <地址> 目标:需与堆栈中的"parking to wait for (at java.util.concurrent.SynchronousQueue$TransferStack)"结合来看。first–>此线程是在等待某个条件的发生,来把自己唤醒,second–>SynchronousQueue不是一个队列,其是线程之间移交信息的机制,当我们把一个元素放入到 SynchronousQueue 中时必须有另一个线程正在等待接受移交的任务,因此这就是本线程在等待的条件。
• 常用指令
jstack 3331:查看线程情况
jstack -F 3331:正常输出不被响应时,使用该指令
jstack -l 3331:除堆栈外,显示关于锁的附件信息
二:通过Java命令排查问题
试题1:某服务器CPU使用率达到99%,排查是哪个程序的哪个线程导致的高CPU
思路:
- 先找到耗CPU高的进程;
- 找到耗CPU高的线程;
- 找到耗CPU高的线程对应的业务代码;
操作:
1.1、执行“top -c
”命令,显示进程运行信息列表,键入大写P
,按CPU使用率降序排列:
1.2、获取到进程PID为10765的进程,使用CPU资源最高19.9%;
至此,已找到耗CPU最高的进程,进程PID为10765,后续命令中需要使用到。
2.1、一个进程内有很多线程,执行“top -Hp 10765
”,显示进程ID为10765的线程列表,键入大写P
,按CPU使用率降序排列:
2.2、其中,PID为10804的线程,CPU使用率最高2.3%;
2.3、将线程ID(10804)按16进制展示,执行指令“printf "%x\n" 10804
”:
至此,找到了CPU使用率最高的线程ID为10804,并获取到10804的16进制标识:2a34
(转为16进制,是因为jstack打印出的线程栈信息中,线程id是通过16进制展示的)
3.1、通过jstack检索到进程(进程ID=10765)中,最耗CPU的线程(线程ID=2a34)的线程栈信息;
执行指令“jstack 10765 | grep "2a34" -C5 --color
”:
C5:打印当前这一行的以及前后5行信息
color:将2a34明显起来(加粗)
至此,找到了耗CPU高的线程对应的线程名称“AsyncLogger-1”,而这个线程名称是我们业务代码中给线程取的名称,可以快速定位到业务代码。
tips:给线程取一个与业务处理相关的名称,对快速定位问题尤为重要。
如果我们没有给线程取名称“AsyncLogger-1”,那打印出来的线程名称可能是:
通过不知名的线程名称“pool-5-thread-1”,以及只包含jdk代码的线程栈信息,我们无法定位到业务代码。
试题2:某java应用大量消耗内存,导致OutOfMemoryError
思路:
- 什么对象消耗内存最大;
- 是否创建了太多的线程;
- 新生的、老年代现在内存使用情况,确认是不是整体内存分配太小了;
- 实时查看新生的、老年代内存使用情况,GC情况
- 代码层检查,是否有大对象创建?需要调用close()或dispose()来回收的资源是否回收了?
操作:
1、执行“jmap -histo:live 10765 | more
”命令,以表格的方式显示存活对象的信息(已按对象所占bytes大小进行降序排列):
其中,10765为进程ID,更多用法,通过“man jmap”寻求帮助。
占内存最多的对象类型是org.apache.logging.log4j.core.async.RingBufferLogEvent,
总共18874368byte (18M),例子中属于正常使用。
tips:如果发现某类对象占用内存很大(几个G的大小),很可能是有问题的。
基本都是因为:该类对象创建太多,且一直未释放。比如:使用完IO资源后,未调用close()
接口关闭、释放资源;又比如:消费者消费速度慢(或停止消费了),而生产者不断往队列中投递任务,导致队列中任务累积过多,任务对象占用内存太多而产生OutOfMemoryError
;
2、执行“pstree -p 10765 | wc -l
”,查看进程内的线程数
其中,10765为进程ID。
每个线程需要分配线程栈内存,创建线程太多,可能导致OutOfMemoryError。
3、执行“jmap -heap 10765
”,查看堆(新生代、老年代)内存分配大小及使用情况
4、执行“jstat -gc 10765 1000
”,查看各个区内存使用情况及GC情况
其中,10765为进程ID,1000为数据刷新间隔的毫秒数
具体字段含义,通过“man jstat”寻求帮助。
主要查看:
- EC:Eden区容量,
- EU:Eden区已使用量,
- OC:Old区容量,
- OU:Old区已使用量;
- YGC:YongGC次数,
- YGCT:YongGC耗时,
- FGC:FullGC次数,
- FGCT:FullGC耗时;
5、代码检查,要求相关同学做codereview(代码评审)