- JVM常用分析工具
- JVM运维实用监控工具
1.JVM常用分析工具
1.1jps
(一)简介
用来查看所有的jvm进程,包括进程ID,进程启动的路径等。
jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。
ps命令我们经常用到,这个命令主要是用来显示当前系统的进程情况。比如有哪些进程及其 id。jps命令也是一样,它的作用是显示当前系统的java进程情况及其id号。我们可以通过它来查看我们到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实例)以及他们的进程号(为下面几个程序做准备),并可通过opt来查看这些进程的详细启动参数。
(二)语法
jps [-q] [-mlvV] [<hostid>]
-q 安静,只显示pid,不显示class名称,jar文件名和传递给main 方法的参数
-m 输出传递给main 方法的参数,在嵌入式jvm上可能是null
-l (显示完整路径)
-v (显示传递给JVM的命令行参数)
-V (显示通过flag文件传递给JVM的参数)
hostid是主机id,默认localhost
(三)测试
# jps
4214 Bootstrap
18096 jar
26423 Jps
默认显示 进程ID 和 启动类的名称。# jps -q
4214
18096
26438
-q 只输出进程ID,而不显示出类的名称# jps -m
4214 Bootstrap start
18096 jar
26453 Jps -m
-m 可以输出传递给 Java 进程(main 方法)的参数# jps -l
4214 org.apache.catalina.startup.Bootstrap
18096 logmon.jar
26468 sun.tools.jps.Jps
-l 可以输出主函数的完整路径(类的全路径)。# jps -v
-v 可以显示传递给 Java 虚拟机的参数。
# jps -V
4214 Bootstrap
26512 Jps
18096 jar
-V 显示通过flag文件传递给JVM的参数
1.2jinfo
(一)简介
负责观察进程运行环境参数,包括Java System属性和JVM命令行参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息
(二)语法
jinfo [ option ] pid
jinfo [ option ] executable core
jinfo [ option ] [server-id@]remote-hostname-or-IP
pid 进程号
executable 产生 core dump 的 java executable
core core file
remote-hostname-or-IP 主机名或ip
server-id 远程主机上的debug server的唯一id
-flags 打印命令行参数
-sysprops 打印系统属性
(三)测试
# jinfo 4214 这个命令包含了 JDK 和 JVM 运行起来时的一些属性,4214 JAVA进程号
1.3jstack
(一)简介
用来观察 jvm 中当前所有线程的运行情况和线程当前状态。
(二)语法
jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
core 将被打印信息的core dump文件
remote-hostname-or-IP 远程debug服务的主机名或ip
server-id 唯一id,假如一台主机上多个远程debug服务
pid 需要被打印配置信息的java进程id,可以用jps查询选项:
-F 当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m 打印java和native c/c++框架的所有栈信息.
(三)测试
# jstack -F 18096 18096 JAVA进程号
1.4jstat
(一)简介
用于输出指定 java 进程的统计信息
利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对进程的classloader,compiler情况;可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量,以及加载类的数量。
(二)语法
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
class:统计classloader的行为
compiler:统计hotspot just-in-time编译器的行为
gc:统计gc行为
gccapacity:统计堆中代的容量、空间
gccause:垃圾收集统计,包括最近引用垃圾收集的事件,基本同gcutil,比gcutil多了两列
gcnew:统计新生代的行为
gcnewcapacity:统计新生代的大小和空间
gcold:统计旧生代的行为
gcoldcapacity:统计旧生代的大小和空间
gcpermcapacity:统计永久代的大小和空间
gcutil:垃圾收集统计
printcompilation:hotspot编译方法统计
-h n 每n个样本,显示header一次
-t n 在第一列显示时间戳列,时间戳时从jvm启动开始计算
<vmid> 就是进程号
<interval> interval是监控时间间隔,单位为微妙,不提供就意味着单次输出
<count> count是最大输出次数,不提供且监控时间间隔有值的话, 就无限打印
(三)测试
# jstat -class 4214 2000 10
(每隔2秒监控一次,一共做10次)
Loaded Bytes Unloaded Bytes Time
9197 18418. 0 0 0.0 12.49
9197 18418. 0 0 0.0 12.49
列名介绍:
Column Description
Loaded 被读入类的数量
Bytes 被读入的字节数(K)
Unloaded 被卸载类的数量
Bytes 被卸载的字节数(K)
Time 花费在load和unload类的时间
1.5jmap
(一)简介
用来监视进程运行中的jvm物理内存的占用情况,该进程内存内,所有对象的情况,例如产生了哪些对象,对象数量。当系统崩溃时,jmap 可以从core文件或进程中获得内存的具体匹配情况,包括Heap size, Perm size等。
(二)语法
jmap [option] <pid>
jmap [option] <executable <core>
jmap [option] [server_id@]<remote server IP or hostname>
-dump:format=b,file=<filename> pid # dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名
-finalizerinfo # 打印等待回收对象的信息
-heap # 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况
-histo[:live] # 打印堆的对象统计,包括对象数、内存大小等等 (因为在dump:live前会进行full gc,因此不加live的堆大小要大于加live堆的大小 )
-permstat # 打印classload类装载器和 jvm heap长久层的信息. 包含包括每个装载器的名字,活跃,地址,父装载器,和其总共加载的类大小。另外,内部String的数量和占用内存数也会打印出来.
-F # 强制,强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
-J # 传递参数给jmap启动的jvm. ,如:-J-Xms256m
(三)测试
# jmap -heap 4214
Attaching to process ID 4214, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.55-b03
using parallel threads in the new generation.
using thread-local object allocation.
Concurrent Mark-Sweep GC
Heap Configuration: # 堆配置情况
MinHeapFreeRatio = 40 # 最小堆的使用比例
MaxHeapFreeRatio = 70 # 最大堆的可用比例
MaxHeapSize = 2684354560 (2560.0MB) # 最大堆空间大小
NewSize = 713031680 (680.0MB) # 新生代分配大小
MaxNewSize = 713031680 (680.0MB) # 最大可用新生代分配大小
OldSize = 5439488 (5.1875MB) # 老年代大小
NewRatio = 2 # 新生代比例
SurvivorRatio = 8 # 新生代与suvivor的比例
PermSize = 251658240 (240.0MB) # perm区大小
MaxPermSize = 251658240 (240.0MB) # 最大可分配perm区大小
G1HeapRegionSize = 0 (0.0MB) # G1堆区大小
Heap Usage: # 堆使用情况
New Generation (Eden + 1 Survivor Space): # 新生代(伊甸区 + survior空间)
capacity = 641728512 (612.0MB) # 伊甸区容量
used = 507109064 (483.6168899536133MB) # 已经使用大小
free = 134619448 (128.38311004638672MB) # 剩余容量
79.0223676394793% used # 使用比例
Eden Space: # 伊甸区
capacity = 570425344 (544.0MB) # 伊甸区容量
used = 503156488 (479.84741973876953MB) # 伊甸区使用
free = 67268856 (64.15258026123047MB) # 伊甸区当前剩余容量
88.2072462755091% used # 伊甸区使用情况
From Space: # survior1区
capacity = 71303168 (68.0MB) # survior1区容量
used = 3952576 (3.76947021484375MB) # surviror1区已使用情况
free = 67350592 (64.23052978515625MB) # surviror1区剩余容量
5.543338551240809% used # survior1区使用比例
To Space: # survior2 区
capacity = 71303168 (68.0MB) # survior2区容量
used = 0 (0.0MB) # survior2区已使用情况
free = 71303168 (68.0MB) # survior2区剩余容量
0.0% used # survior2区使用比例
concurrent mark-sweep generation: # 老生代使用情况
capacity = 1971322880 (1880.0MB) # 老生代容量
used = 1514740296 (1444.5689163208008MB) # 老生代已使用容量
free = 456582584 (435.4310836791992MB) # 老生代剩余容量
76.83877214472345% used # 老生代使用比例
Perm Generation: # perm区使用情况
capacity = 251658240 (240.0MB) # perm区容量
used = 57814400 (55.1361083984375MB) # perm区已使用容量
free = 193843840 (184.8638916015625MB) # perm区剩余容量
22.973378499348957% used # perm区使用比例
28645 interned Strings occupying 3168232 bytes.
2.JVM运维实用监控工具:VirtualVM
2.1简介
VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高性能分析的精度。
2.2性能分析的主要方式
(一)监视
监视是一种用来查看应用程序运行时行为的一般方法。通常会有多个视图(View)分别实时地显示 CPU 使用情况、内存使用情况、线程状态以及其他一些有用的信息,以便用户能很快地发现问题的关键所在。
(二)转储
转储:性能分析工具从内存中获得当前状态数据并存储到文件用于静态的性能分析。Java 程序是通过在启动 Java 程序时添加适当的条件参数来触发转储操作的。它包括以下三种:
系统转储:JVM 生成的本地系统的转储,又称作核心转储。一般的,系统转储数据量大,需要平台相关的工具去分析,如 Windows 上的 windbg 和 Linux 上的 gdb。
Java 转储:JVM 内部生成的格式化后的数据,包括线程信息,类的加载信息以及堆的统计数据。通常也用于检测死锁。
堆转储:JVM 将所有对象的堆内容存储到文件
(三)快照
快照:应用程序启动后,性能分析工具开始收集各种运行时数据,其中一些数据直接显示在监视视图中,而另外大部分数据被保存在内部,直到用户要求获取快照,基于这些保存的数据的统计信息才被显示出来。快照包含了应用程序在一段时间内的执行信息,通常有 CPU 快照和内存快照两种类型。
CPU 快照:主要包含了应用程序中函数的调用关系及运行时间,这些信息通常可以在 CPU 快照视图中进行查看。
内存快照:主要包含了内存的分配和使用情况、载入的所有类、存在的对象信息及对象间的引用关系等。这些信息通常可以在内存快照视图中进行查看。
(四)性能分析
性能分析:性能分析是通过收集程序运行时的执行数据来帮助开发人员定位程序需要被优化的部分,从而提高程序的运行速度或是内存使用效率,主要有以下三个方面:
CPU 性能分析:CPU 性能分析的主要目的是统计函数的调用情况及执行时间,或者更简单的情况就是统计应用程序的 CPU 使用情况。通常有 CPU 监视和 CPU 快照两种方式来显示 CPU 性能分析结果。
内存性能分析:内存性能分析的主要目的是通过统计内存使用情况检测可能存在的内存泄露问题及确定优化内存使用的方向。通常有内存监视和内存快照两种方式来显示内存性能分析结果。
线程性能分析:线程性能分析主要用于在多线程应用程序中确定内存的问题所在。一般包括线程的状态变化情况,死锁情况和某个线程在线程生命期内状态的分布情况等
2.3图示
(一)内存分析
(二)CPU分析
(三)线程分析
(四)快照功能
(五)转储功能
线程转储的生成与分析
VisualVM 能够对正在运行的本地应用程序生成线程转储,把活动线程的堆栈踪迹打印出来,帮助我们有效了解线程运行的情况,诊断死锁、应用程序瘫痪等问题。