原文地址:http://www.javatang.comhtml
当服务器CPU100%的时候,经过定位占用资源最大的线程定位到 VM Thread:java
"VM Thread" prio=10 tid=0x00007fbea80d3800 nid=0x5e9 runnable
这个时候须要使用 jstat -gc <pid> <period> <times>
命令查看gc的信息,显示结果以下:bash
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
64.0 64.0 0.0 0.0 332992.0 0.0 666304.0 73192.5 83968.0 83967.9 6893 17.576 6882 2705.923 2723.499
结果中每一个项目的含义能够参考官方对jstat的文档,简单翻译以下:服务器
- S0C: Young Generation第一个survivor space的内存大小 (kB).
- S1C: Young Generation第二个survivor space的内存大小 (kB).
- S0U: Young Generation第一个Survivor space当前已使用的内存大小 (kB).
- S1U: Young Generation第二个Survivor space当前已经使用的内存大小 (kB).
- EC: Young Generation中eden space的内存大小 (kB).
- EU: Young Generation中Eden space当前已使用的内存大小 (kB).
- OC: Old Generation的内存大小 (kB).
- OU: Old Generation当前已使用的内存大小 (kB).
- PC: Permanent Generation的内存大小 (kB)
- PU: Permanent Generation当前已使用的内存大小 (kB).
- YGC: 从启动到采样时Young Generation GC的次数
- YGCT: 从启动到采样时Young Generation GC所用的时间 (s).
- FGC: 从启动到采样时Old Generation GC的次数.
- FGCT: 从启动到采样时Old Generation GC所用的时间 (s).
- GCT: 从启动到采样时GC所用的总时间 (s).
JDK8的结果稍微有所不一样,结果含义能够参考:http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html。oracle
上面中的Young Generation、Permanent Generation和Old Generation等概念有一些混乱,这里简要的进行说明。简单来讲,JVM内存由堆(Heap)和非堆(Non-heap)内存组成,前者共运行在JVM之上的程序使用,后者供JVM本身使用。优化
堆内存的组成以下:spa
非堆内存由 Permanent Generation 和 Code Cache 两部分组成:操作系统
-Xms
和 -Xmx
分别设置最小和最大堆内存-Xmn
设置,-XX:SurvivorRatio=m
设置 Eden和 两个Survivor区的大小比值;-XX:NewRatio=n
设置 New Generation 和 Old Generation 的大小比值。非堆内存由 -XX:PermSize=n
和 -XX:MaxPermSize=n
分别设置最小和最大非堆内存大小线程
介绍完上面的概念以后,咱们再来看最上面的日志信息,有两个地方有问题:
一是FGC(彻底GC)的数量太大了,正常来讲FGC应该占整个GC(YGC+FGC)的1%到5%才正常,上面日志上彻底GC的次数太多了;二是日志中PU的值太大了,基本上已经达到设置的PC了,所以须要增大MaxPermSize的值。
不过这只是权宜之计,出现这么大的非堆内存,确定什么地方出现了问题,还须要进一步找到占用内存的缘由,这也是后面文章所要说的。翻译