定位问题时,知识和经验是关键基础、数据(运行日志、异常堆栈、GC日志、线程快照、堆转储快照)是依据、工具是运用知识处理数据的手段。
jps(JVM Process Status Tool):可以列出正在运行的虚拟机进程,并显示虚拟机执行的主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一 ID(Local Virtual Machine Identity,LVMID)。
jps 命令格式:jps [options] [hostid]
jstat(JVM Statistics Monitoring Tool):监视虚拟机各种运行状态信息,包括类装载、内存、垃圾收集、JIT等;在没有 GUI 图形界面,是运行期间定位虚拟机性能问题的首选工具。
jstat 命令格式:jstat [options]
,其中参数 interval 和 count 表示查询间隔和次数。而 options 表示用户希望查询的虚拟机信息,主要分为三类:类装载,垃圾收集,运行期编译状况:
在 jdk 1.8 中,关于永久代的变成:-gcmetacapacity
:
MCMN:最小元数据容量,MCMX:最大元数据容量,MC:当前元数据空间大小,CCSMN:最小压缩类空间大小,CCSMX:最大压缩类空间大小,CCSC:当前压缩类空间大小,YGC:年轻代垃圾回收次数,FGC:老年代垃圾回收次数,FGCT:老年代垃圾回收消耗时间,GCT:垃圾回收消耗总时间。
jstat 输出样例:
其中 S0 和 S1 指 Survivor0 区和 Survivor1区,E 即 Eden 区,O 指老年代,M 指 MetaSpace,元数据空间,CCS 是压缩使用比例,YGC:年轻代垃圾回收次数,FGC:老年代垃圾回收次数,FGCT:老年代垃圾回收消耗时间,GCT:垃圾回收消耗总时间。
jinfo(Configuration Info for Java):实时地查看和调整虚拟机各项参数。虽然 jps -v
可以查看虚拟机启动时显式指定的参数,但是无法查看一些系统默认的参数。
jinfo 命令格式:jinfo [option] pid
执行样例:查询 CMSInitiatingOccupancyFraction 参数
jmap(Memory Map for Java)命令用于生成堆转储快照(一般称为 heapdump 或 dump 文件)。
其他可生成 heapdump 的方式:
-XX:+HeapDumpOnOutOfMemoryError
,可以让虚拟机在 OOM 异常出现之后自动生成 dump 文件-XX:+HeapDumpOnCtrlBreak
然后使用 Ctrl+Break
生成jmap 还可以查询 finalize 执行队列、Java 堆和永久代的详细信息
jmap 命令格式:jmap [options] vmid
jhat(JVM Heap Analysis Tool)用于分析 jmap 生成的 heapdump。其内置了一个微型的 HTTP 服务器,可以在浏览器查看分析结果。
实际很少用 jhat,主要有两个原因:
演示:
在浏览器键入 http://localhost:7000/
就可以看到分析结果:
jstack(Stack Trace for Java)命令可以用于生成虚拟机当前时刻的线程快照(一般称为 threaddump 或 javacore 文件)。javacore 主要目的是定位线程出现长时间停顿的原因,比如死锁、死循环、请求外部资源响应长等。另外 JDK 1.5 后 Thread 类新增了 getAllStackTraces()
方法,可以基于此自己增加管理页面来分析。
jstack 命令格式:jstack [options] vmid
,其 options :
样例:
现代虚拟机的实现慢慢地和虚拟机规范产生差距,如果要分析程序如果执行,最常见的就是通过软件调试工具(GDB、Windbg等)断点调试,但是对于 Java 来说,很多执行代码是通过 JIT 动态生成到 CodeBuffer 中的。
HSDIS 是官方推荐的 HotSpot 虚拟机 JIT 编译代码的反汇编工具,它包含在 HotSpot 虚拟机的源码中,但没有提供编译后的程序,可以自己下载放到 JDK 的相关目录里。它作用是让 HotSpot 的 -XX:+PrintAssembly
指令调用它来把动态生成的本地代码还原为汇编代码输出,同时还生成大量有价值的注释。
屏幕出现如下所示内容:
JConsole(Java Monitoring and Management Console)是一种基于 JMX 的可视化监控和管理工具,它管理部分的功能是针对 MBean 进行管理,由于 MBean 可以使用代码、中间件服务器或者所有符合 JMX 规范的软件进行访问,因此这里着重介绍 JConsole 的监控功能。
通过 JDK/bin 目录下的“jconsole.exe”启动 JConsole,会自动搜索本机所有虚拟机进程:
双击选择本地进程,进入主界面,包括“概述”、“内存”、“线程”、“类”、“VM 摘要”、“MBean”,6个页面:
其中,概述显示整个虚拟机主要运行数据的概览,包括堆内存使用情况,线程,类,CPU 使用情况,4种信息的曲线图。
内存页签相当于可视化的 jstat 命令,用于监视受收集器管理的虚拟机内存的变化趋势。
线程页签相当于可视化的 jstack 命令,遇到线程停顿时可以使用这个页签进行监控分析。
VIsualVM(All-in-One Java Troubleshooting Tool)是目前为止JDK发布的功能最强调的运行监控和故障处理程序,另外还支持性能分析,它还有一个很大的优点:不需要被监视的程序基于特殊 Agent 运行,因此对应用程序的实际性能影响很小,可直接应用在生成环境中。
VisualVM 是基于 NetBeans 平台开发,具备插件扩展功能的特性,基于插件可以做到:
可以自动安装插件(也可手工安装):
VisualVM 功能:
本章介绍了随 JDK 发布的 6 个命令行工具以及 2 个可视化的故障处理工具,灵活运行这些工具可以给问题处理带来很多便利。