jvm调优
java 

垃圾回收

CMS 收集器无法处理浮动垃圾(Floating Garbage),可能会出现 Concurrent Mode Failure 失败,而导致另一次 STW 的 Full GC 的产生。 由于 CMS 并发清理阶段用户线程还在运行,伴随着程序运行自然就还会有新的垃圾不断产生,这部分垃圾出现在标记过程之后,CMS 无法在当次收集中处理掉它们,只好留到下次

在常见的线上问题中,如下问题比较常见:

  • 内存泄露
  • 某个进程CPU突然飙升
  • 线程死锁
  • 响应变慢

如果遇到上述问题,我们可以基于监控工具来定位问题。java中常用的分析监控工具有: jpsjstatjinfojmapjhatjstack

jps: JVM进程状况

jps用来查看进程的状况,语法如下:

jps [options] [hostid]
参数:
-q: 不输出类名、jar名和传入main方法的参数
-l: 输出main类或jar的全限名
-m: 输出传入main方法的参数
-v: 输出传入JVM的参数

示例
jps -l
    7605 sun.tools.jps.Jps
    13598 com.caucho.server.resin.Resin

jstat: JVM 统计信息监控工具

jstat 是用于查看虚拟机各种运行状态的命令行工具,它可以显示本地或远程虚拟机中的类装载、内存、垃圾收集、jit编译等运行数据。其具体用法如下:

jstat [options] pid [interval[s|ms] [count]]
- options: 选项,我们一般使用 -gcutil 查看gc情况
- interval: 间隔时间,单位为秒或者毫秒
- count: 打印次数,如果缺省则打印无数次
option用途例子
class用于查看类加载情况的统计jstat -class <pid> : 显示加载class的数量,所占空间等信息
complier查看HotSpot中即时编译情况统计jstat -compiler pid: 显示VM实时编译数量等信息
gc查看JVM中堆的垃圾收集情况的统计jstat -gc pid
gccapacity查看新生代、老生代及持久代的存储容量情况jstat -gccapacity: 可以显示VMware内存中三代对象的使用和占用大小
gccause查看垃圾收集的统计情况,如果有发生垃圾收集,它还会显示最后一次及当前正在发生的垃圾收集原因jstat -gccause: 显示gc原因
gcnew查看新生代垃圾内含物的情况jstat -gcnew pid: new 对象的信息
gcnewcapacity用于查看新生代的存储容量情况jstat -gcnewcapacity pid: new 对象的信息及其占用量
gcold查看老生代及持久代GC情况jstat -gcold pid: old 对象的信息
gcoldcapacity用于查看老生代的容量jstat -gcoldcapacity: old对象的信息及其占用量
gcpermacpacity用于查看持久代的容量jstat -gcpermcapacity pid: 持久代对象的信息
gcutil查看新生代、老年代及持久代垃圾收集情况jstat -util pid: 统计gc信息

示例

jstat -gc <pid>

结果 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
43520.0 43520.0 0.0 0.0 611840.0 371440.0 1398272.0 1077246.3 34816.0 33485.4 3584.0 3324.3 7 1.202 32 34.763 35.966

jstat -gcutil <pid> 5000

S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 1.30 19.87 15.23 95.56 92.59 269 20.071 2 0.136 20.207 1.29 0.00 13.94 15.23 95.56 92.59 270 20.138 2 0.136 20.274 0.00 1.35 9.45 15.23 95.56 92.59 271 20.204 2 0.136 20.341

参数说明:

  • S0C: 年轻代中第一个survivor(幸存区)的容量 (字节) 
  • S1C: 年轻代中第二个survivor(幸存区)的容量 (字节) 
  • S0U: 年轻代中第一个survivor(幸存区)目前已使用空间 (字节) 
  • S1U: 年轻代中第二个survivor(幸存区)目前已使用空间 (字节) 
  • EC: 年轻代中Eden(伊甸园)的容量 (字节) 
  • EU: 年轻代中Eden(伊甸园)目前已使用空间 (字节) 
  • OC: 老年代大小 (字节) 
  • OU: 老年代使用大小 (字节) 
  • MC: 方法区大小 (字节) 
  • MU: 方法区使用大小 (字节) 
  • CCSC: 压缩类空间大小 (字节) 
  • CCSU: 压缩类空间使用大小 (字节) 
  • YGC: 年轻代垃圾回收次数
  • YGCT: 年轻代垃圾回收消耗时间
  • FGC: 老年代垃圾回收次数
  • FGCT: 老年代垃圾回收消耗时间
  • GCT: 垃圾回收消耗总时间
  • NGCMN: 年轻代(young)中初始化(最小)的大小 (字节) 
  • NGCMX: 年轻代(young)的最大容量 (字节) 
  • NGC: 年轻代(young)中当前的容量 (字节) 
  • OGCMN: old代中初始化(最小)的大小 (字节) 
  • OGCMX: old代的最大容量 (字节) 
  • OGC: old代当前新生成的容量 (字节) 
  • PGCMN: perm代中初始化(最小)的大小 (字节) 
  • PGCMX: perm代的最大容量 (字节)   
  • PGC: perm代当前新生成的容量 (字节) 
  • S0: 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比 
  • S1: 年轻代中第二个survivor(幸存区)已使用的占当前容量百分比 
  • E: 年轻代中Eden(伊甸园)已使用的占当前容量百分比 
  • O: old代已使用的占当前容量百分比 
  • P: perm代已使用的占当前容量百分比 
  • S0CMX: 年轻代中第一个survivor(幸存区)的最大容量 (字节) 
  • S1CMX : 年轻代中第二个survivor(幸存区)的最大容量 (字节) 
  • ECMX: 年轻代中Eden(伊甸园)的最大容量 (字节) 
  • DSS: 当前需要survivor(幸存区)的容量 (字节)(Eden区已满) 
  • TT: 持有次数限制 
  • MTT: 最大持有次数限制 

jinfo: Java 配置信息

jinfo 可以获取当前线程的jvm运行和启动信息,使用如下:

jinfo [option] pid

jmap: Java 内存映射工具

jmap 命令用于将堆转存成快照,

查看内存中类的情况:

jmap -histo:live <pid>
local_offer #java 
navigate_before navigate_next