【0】README
0.1)本文文字描述转自 “深入理解jvm”,旨在了解 虚拟机性能监控与故障处理工具的基础知识(仅仅在于了解);
【1】概述
1)给一个系统定位问题的时候,知识,经验是关键基础,数据是依据,工具是运用知识处理数据的手段。这里说的数据包括:运行日志,异常堆栈,GC日志,线程快照,堆转储快照等;
2)JDK的命令行工具:jdk 的bin 目录是jdk的工具目录,这些命令行工具大多数是 jdk/lib/tools.jar 类库的一层薄包装而已,它们主要的功能代码是在 tools 类库中实现的;
3)Sun JDK 监控和故障处理工具
3.1)jps:虚拟机进程状况工具(jps==jvm process status tool),它可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一ID;
3.2)jstat:虚拟机统计信息监视工具(jstat==jvm statistics monitoring tool),用于监视虚拟机各种运行状态信息的命令行工具。他可以显示本地或者远程虚拟机进程中的类装载,内存,垃圾收集,JIT编译等运行数据,在没有GUI的时候,它是运行期定位虚拟机性能问题的首选工具;
- 3.2.1)命令格式: jstat [option vmid [interval [s|ms] [count]] ]
- 3.2.2)参数interval 和 count 表示查询间隔 和 次数,如果省略这两个参数,说明只查询一次。如需要每250ms 查询一次进程 2764 垃圾收集状况,一共查询20次,命名应该是: jstat -gc 2764 250 20
3.3)jinfo:java配置信息工具
3.3.1)jinfo的作用(function):
- f1)实时地查看和调整虚拟机各项参数。使用jps命令的-v 参数可以查看jvm启动时显式指定的参数列表,但如果想知道未被显式指定的参数的系统默认值,就只能使用 jinfo的-flag 选项进行查询了;
- f2)jinfo还可以使用 -sysprops 选项把jvm 进程的 System.getProperties()的内容打印出来;
- f3)jinfo加入了运行期修改参数的能力,可以使用 -flag[+|-] name 或 -flag name=value 修改一部分运行期可写的jvm 参数值;(jinfo 在 windows平台的功能有较大限制,只提供了最基本的-flag选项)
3.3.2)jinfo命令:jinfo [option] pid //pid 通过 jps 来查看
C:\Users\lenovo>jps -l
5392 com.jvm.chapter4.MyTest
1272
5272 sun.tools.jps.JpsC:\Users\lenovo>jinfo 5392
Attaching to process ID 5392, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.60-b23
Java System Properties:java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.60-b23
sun.boot.library.path = C:\Program Files\Java\jre1.8.0_60\bin
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = ;
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
sun.os.patch.level = Service Pack 1
sun.java.launcher = SUN_STANDARD
user.script =
user.country = CN
user.dir = E:\bench-cluster\cloud-data-preprocess\jvm
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_60-b27
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = C:\Program Files\Java\jre1.8.0_60\lib\endorsed
line.separator =java.io.tmpdir = D:\Personal\Temp\
java.vm.specification.vendor = Oracle Corporation
user.variant =
os.name = Windows 7
sun.jnu.encoding = GBK
java.library.path = C:\Program Files\Java\jre1.8.0_60\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:/Program Files/Java/jre1.8.0_60/bin/server;C:/Program Files/Java/jre1.8.0_60/bin;C:/P
rogram Files/Java/jre1.8.0_60/lib/amd64;C:\ProgramData\Oracle\Java\javapath;D:\Program Files (x86)\ARM\ADSv1_2\bin;C:\Program Files (x86)\Common Files\NetSarang;C:\jdk1.8.0_60\bin;D:\Development\LAMP\
PHP;C:\ProgramData\ComposerSetup\bin;c:\windows\system32;C:\Users\lenovo\AppData\Roaming\Composer\vendor\bin;D:\Development\LAMP\Apache24\bin;D:\Program Files\nodejs;D:\Program Files (x86)\MySQL\MySQLServer 5.1\bin;D:\Program Files (x86)\Rational\common;D:\Program Files (x86)\Microsoft Visual Studio\Common\MSDev98\Bin;D:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin;D:\Development\Java-rel
ated\eclipse-java-luna-SR1a-win32-x86_64\eclipse;;.
java.specification.name = Java Platform API Specification
java.class.version = 52.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 6.1
user.home = C:\Users\lenovo
user.timezone =
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = GBK
java.specification.version = 1.8
user.name = lenovo
java.class.path = E:\bench-cluster\cloud-data-preprocess\jvm\bin
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = com.jvm.chapter4.MyTest
java.home = C:\Program Files\Java\jre1.8.0_60
user.language = zh
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.8.0_60
java.ext.dirs = C:\Program Files\Java\jre1.8.0_60\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path = C:\Program Files\Java\jre1.8.0_60\lib\resources.jar;C:\Program Files\Java\jre1.8.0_60\lib\rt.jar;C:\Program Files\Java\jre1.8.0_60\lib\sunrsasign.jar;C:\Program Files\Java\jre1.8
.0_60\lib\jsse.jar;C:\Program Files\Java\jre1.8.0_60\lib\jce.jar;C:\Program Files\Java\jre1.8.0_60\lib\charsets.jar;C:\Program Files\Java\jre1.8.0_60\lib\jfr.jar;C:\Program Files\Java\jre1.8.0_60\clas
ses
java.vendor = Oracle Corporation
file.separator = \
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = amd64VM Flags:
Non-default VM flags: -XX:CICompilerCount=3 -XX:InitialHeapSize=132120576 -XX:MaxHeapSize=2088763392 -XX:MaxNewSize=696254464 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=44040192 -XX:OldSize=88080384 -XX
:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
Command line: -Dfile.encoding=GBK
3.4)jmap:java内存映像工具(memory map for java):
- 3.4.1)该命令用于生成堆转储快照(一般称为 heapdump 或 dump文件)。
- 3.4.2)jmap的作用并不仅仅是为了获取dump文件,它还可以查询 finalize 执行队列,java堆和永久代的详细信息;
- 3.4.3)jmap 工具主要选项
3.4)jstack:java堆栈跟踪工具(stack trace for java):该命令用于生成jvm 当前时刻的线程快照(一般称为 threaddump 或 javacore 文件)。
- 3.4.1)线程快照就是当前jvm 内每一条线程正在执行的方法堆栈的集合,生成线程快照的目的是 定位线程出现长时间停顿的原因,如线程间死锁,死循环,请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因;
- 3.4.2)jstack命令格式:jstack [option] vimd
- 3.4.3)jstack 工具主要选项
3.5)HSDIS:JIT 生成代码反汇编(通过软件调试工具来进行断点调试)
1)problem:分析程序如何执行,通过软件调试工具(GDB,Winbg)来断点调试是最常见的手段,但这样的调试方式在jvm 中会遇到很大的麻烦,因为大量执行代码是通过JIT编译器动态生成到 CodeBuffer中的,没有很简单的手段来处理这种混合模式的调试。
2)solution:HSDIS是一个Sun官方推荐的HotSpot 虚拟机JIT编译代码的反汇编插件,它包含在HotSpot虚拟机的源码之中,但没有提供编译后的程序。在 Project Kenai 的网站可以下载到源码(for downloading ,please visit https://kenai.com/projects/base-hsdis);
3)作用:让HotSpot的-XX:+PrintAssembly 指令调用它来把动态生成的本地代码还原出汇编代码输出,同时还生成了大量非常有价值的注释,这样我们就可以通过输出的代码来分析问题。
Attention)
- A1)若读者使用的是Debug version 或 FastDebug version的HotSpot,那可以直接通过-XX:+PrintAssembly 指令使用插件;若使用的是 Product version的HotSpot,那还要额外加入一个 -XX:+UnlockDiagnosticVMOptions 参数;
4) JDK的可视化工具
4.1)JConsole:java监视与管理控制台
- 4.1.1)启动JConsole: 双击在 JDK/bin 目录下的jconsole.exe 文件,将自动搜索出本机运行的所有jvm 进程,不需要用户自己来使用jps 查询(双击后监控该线程);
- 4.1.2)内存监控:内存标签相当于可视化的 jstat命令,用于监控受收集器管理的虚拟机内存(java堆和永久代)的变化趋势;
- 4.1.3)线程监控:线程标签的功能相当于可视化的jstack命令,遇到线程停顿时可以使用这个标签进行监控分析;
4.2)visualVM:多合一故障处理工具(目前为止,它是随JDK发布的功能最强大的运行监视和故障处理程序)
- 4.2.1)作用(functions)
- f1)显示虚拟机进程以及进程的配置,环境信息(jps,jinfo);
- f2)监视应用程序的CPU, GC, 堆, 方法区以及线程的信息(jstat、jstack);
- f3)dump 以及分析堆转储快照(jmap,jhat);
- f4)方法级的程序运行性能分析,找出被调用最多,运行时间最长的方法;
- f5)离线程序快照,收集程序的运行时配置,线程dump,内存dump 等信息建立一个快照,可以将快照发送开发者处进行bug 反馈;
- f6)其他plugins 的无限可能性;(在对应用程序进行检测时,还需要加载相应的插件);
2.2)VisualVM 主要特性的兼容性列表