JVM性能监控与故障处理工具

x33g5p2x  于2021-12-18 转载在 其他  
字(6.0k)|赞(0)|评价(0)|浏览(378)

引言

在 应用服务出现模型的卡顿或者CPU飙升等问题时,总是要分析一下对应的进程的JVM状态以定位问题和解决问题并做出响应的优化,在这个过程中java自带的一些状态监控 命令工具就非常方便了。

1、jps:JVM进程状况工具

JDK中很多的小工具都参考 了unix的命名方式,jps 就是其中的典型。除了名称和UNIX中的ps相似之外,功能也和ps命令类似:可以列出正在运行的虚拟机进程,并显示虚拟机执行主类( main class,main()函数所在类)名称及这些进程的 本地虚拟机唯一id。

命令格式:

jps [options] [hostid]

options参数解释:

  • -l:输出主类全名或jar 路
  • -q:只输出LVMD(Local Virtual Machine Identifier , LVMID)
  • -m:输出JVM启动时传递给main()的参数
  • -v:输出JVM启动时显示指定的JVM参数

jps执行样例:

2、jstat:JVM统计信息监控工具

jstat命令式使用比较频繁的命令,主要用来显示 本地或者远程虚拟机中类装载、内存、垃圾收集、JIT编译等运行数据。 在没有GUI图形界面,只提供了纯文本的控制台环境的服务器上,它将是运行期间定位虚拟机性能问题的首选工具。

命令格式:

jstat  [option]  LVMID  [interval ] [count]

其中LVMID是进程id,interval是打印间隔时间(毫秒),count是打印次数,如果省略这两个参数,说明只查询一次。

option参数解释:

选项作用
-class监视类装载,类卸载,总空间及类装载所消耗的时间
-gc监视java堆状况,包括Eden区,两个survivor区,老年代,永久代等容量、已经使用空间、GC时间合计信息
-gcutil监视内容与-gc基本相同,但是输出主要关注已使用空间站总空间的百分比
-gccapacity监视内容与-gc基本相同,但是输出主要关注java堆各个区域使用到的最大、最小空间
-gccause与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew监视新生代的GC状况
-gcnewcapacity监视内容与-gcnew基本相同,输出主要关注使用到的最大最小空间
-gcold监视老年代GC状况
-gcoldcapacity<br>监视内容与-gcold基本相同,输出主要关注使用到的最大、最小空间<br>
-gcpermcapacity输出永久代使用到的最大、最小空间
-compiler输出JIT编译器编译过的方法、耗时等信息
-printcompilation输出已经被JIT编译的方法

例如需要 每250秒查询一次进程3900垃圾收集状况,一共查询20次,执行命令如下:

jstat -gc 3900 250 20

字段解释:

  • S0C survivor0大小
  • S1C survivor1大小
  • S0U survivor0已使用大小
  • S1U survivor1已使用大小
  • EC Eden区大小
  • EU Eden区已使用大小
  • OC 老年代大小
  • OU 老年代已使用大小
  • MC 方法区大小
  • MU 方法区已使用大小
  • CCSC 压缩类空间大小
  • CCSU 压缩类空间已使用大小
  • YGC 年轻代垃圾回收次数
  • YGCT 年轻代垃圾回收消耗时间
  • FGC 老年代垃圾回收次数
  • FGCT 老年代垃圾回收消耗时间
  • GCT 垃圾回收消耗总时间

-gcutil和-gc参数类似,只不过输出字段不是实际值,而是百分比。

字段解释:

  • S0 survivor0使用百分比
  • S1 survivor1使用百分比
  • E Eden区使用百分比
  • O 老年代使用百分比
  • M 元数据区使用百分比
  • CCS 压缩使用百分比
  • YGC 年轻代垃圾回收次数
  • YGCT 年轻代垃圾回收消耗时间
  • FGC 老年代垃圾回收次数
  • FGCT 老年代垃圾回收消耗时间
  • GCT 垃圾回收消耗总时间

3、jinfo:Java配置信息工具

jinfo的作用是实时的查看和调整虚拟机 各项参数。使用jps命令的-v参数可以查看虚拟机启动时显式指定的参数列表。如果想知道未被显式指定的参数系统默认值,那就需要查找相关资料或者使用jinfo命令配合相关参数进行查看。

命令格式:

jinfo [option] <pid>

options:参数解释

  • -flag <name> 打印指定名称的参数
  • -flag [+|-]<name> 打开或关闭参数
  • -flag <name>=<value> 设置参数
  • -flags 打印所有参数
  • -sysprops 打印系统配置
  • <no option> 打印上面两个选项

常用示例展示:

1)、查看JVM参数和系统配置

jinfo 11666

jinfo  -flags 11666

jinfo   -sysprops 11666

2)、查看打印GC日志参数

jinfo -flag PrintGC 11666

jinfo -flag PrintGCDetails 11666

3)、关闭GC参数

jinfo -flag -PrintGC 11666

jinfo -flag -PrintGCDetails 11666

还可以使用下面的命令查看哪些参数可以使用jinfo命令来管理:

java -XX:+PrintFlagsFinal -version | ``grep manageable

4、jmap:java内存映像工具

jmap是用来生成对dump文件和查看堆相关的各类信息命令,例如查看finalize执行队列,heap的详细信息和 使用情况。

命令格式:

jmap [option] <pid> (连接正在执行的进程)
jmap [option] <executable <core> (连接一个core文件)
jmap [option] [server_id@]<remote server IP or hostname> (链接远程服务器)

option参数解释:

  • <none> to print same info as Solaris pmap
  • -heap 打印java heap摘要
  • -histo[:live] 打印堆中的java对象统计信息
  • -clstats 打印类加载器统计信息
  • -finalizerinfo 打印在f-queue中等待执行finalizer方法的对象
  • -dump:<dump-options> 生成java堆的dump文件

dump-options:

live 只转储存活的对象,如果没有指定则转储所有对象

format=b 二进制格式

file=<file> 转储文件到 <file>

  • -F 强制选项

常用示例:

1)、jmap -dump:live,``format``=b,``file``=dump.hprof 11666

输出:

Dumping heap to ``/dump``.hprof ...

Heap dump ``file created

这个命令是要把java堆中的存活对象信息转储到dump.hprof文件

2)、jmap -finalizerinfo 11666

输出:

Attaching to process ID 11666, please wait...

Debugger attached successfully.

Server compiler detected.

JVM version is 24.71-b01

Number of objects pending for finalization: 0

输出结果的含义为当前没有在等待执行finalizer方法的对象

3)、jmap -heap 11666

输出堆的详细信息

Attaching to process ID 11666, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.25-b02

using thread-local object allocation.
Parallel GC with 4 thread(s)

Heap Configuration: //堆内存初始化配置
   MinHeapFreeRatio         = 0 //对应jvm启动参数-XX:MinHeapFreeRatio设置JVM堆最小空闲比率(default 40)
   MaxHeapFreeRatio         = 100 //对应jvm启动参数 -XX:MaxHeapFreeRatio设置JVM堆最大空闲比率(default 70)
   MaxHeapSize              = 1073741824 (1024.0MB) //对应jvm启动参数-XX:MaxHeapSize=设置JVM堆的最大大小
   NewSize                  = 22020096 (21.0MB) //对应jvm启动参数-XX:NewSize=设置JVM堆的新生代的默认大小
   MaxNewSize               = 357564416 (341.0MB) //对应jvm启动参数-XX:MaxNewSize=设置JVM堆的新生代的最大大小
   OldSize                  = 45088768 (43.0MB) //对应jvm启动参数-XX:OldSize=<value>:设置JVM堆的老年代的大小
   NewRatio                 = 2 //对应jvm启动参数-XX:NewRatio=:新生代和老生代的大小比率
   SurvivorRatio            = 8 //对应jvm启动参数-XX:SurvivorRatio=设置新生代中Eden区与Survivor区的大小比值
   MetaspaceSize            = 21807104 (20.796875MB) // 元数据区大小
   CompressedClassSpaceSize = 1073741824 (1024.0MB) //类压缩空间大小
   MaxMetaspaceSize         = 17592186044415 MB //元数据区最大大小
   G1HeapRegionSize         = 0 (0.0MB) //G1垃圾收集器每个Region大小

Heap Usage: //堆内存使用情况
PS Young Generation 
Eden Space: //Eden区内存分布
   capacity = 17825792 (17.0MB) //Eden区总容量
   used     = 12704088 (12.115562438964844MB) //Eden区已使用
   free     = 5121704 (4.884437561035156MB) //Eden区剩余容量
   71.26801434685203% used //Eden区使用比率
From Space: //其中一个Survivor区的内存分布
   capacity = 2097152 (2.0MB)
   used     = 1703936 (1.625MB)
   free     = 393216 (0.375MB)
   81.25% used
To Space: //另一个Survivor区的内存分布
   capacity = 2097152 (2.0MB)
   used     = 0 (0.0MB)
   free     = 2097152 (2.0MB)
   0.0% used
PS Old Generation
   capacity = 52428800 (50.0MB) //老年代容量
   used     = 28325712 (27.013504028320312MB) //老年代已使用
   free     = 24103088 (22.986495971679688MB) //老年代空闲
   54.027008056640625% used //老年代使用比率
interned Strings occupying 2075304 bytes.

4)、jmap -histo:live 11666 | ``more

输出存活对象统计信息

输出:

num     #instances         #bytes  class name
----------------------------------------------
1:         46608        1111232  java.lang.String
2:          6919         734516  java.lang.Class
3:          4787         536164  java.net.SocksSocketImpl
4:         15935         497100  java.util.concurrent.ConcurrentHashMap$Node
5:         28561         436016  java.lang.Object

5、jhat:虚拟机堆转储快照分析工具

jhat命令和jmap搭配使用,来分析jmap生成的堆转储快照。jhat内置了一个小型的HTTP/HTML服务器,生成dump分析结果后,可以在浏览器中进行查看。不过在实际环境中,很少有人会使用该命令就行快照分析,除非手头上别无选择。主要原因:一是一般不会在部署应用程序的服务器上直接分析 dump文件,即使可以这样做,也会尽量将dump文件复制到别的机器上完成分析,因为分析工作是一个耗时而且消耗硬件资源的过程。另一个原因就是jhat的分析功能相对来说比较简陋。

命令格式:

jhat [option] [dumpfile]

option参数解释:

  • -stack false: 关闭对象分配调用堆栈的跟踪
  • -refs false: 关闭对象引用的跟踪
  • -port <port>: HTTP服务器端口,默认是7000
  • -debug <int>: debug级别

0: 无debug输出

1: Debug hprof file parsing

2: Debug hprof file parsing, no server

  • -version 分析报告版本

6、jstack:java堆栈跟踪工具

jstack是用来查看JVM线程快照的命令,线程快照是当前JVM线程正在执行的方法堆栈 集合。使用jstack命令可以定位线程出现长时间卡顿的原因,例如死锁, 死循环等。jstack还可以查看 程序崩溃是生成的core文件中的stack信息。

命令格式:

jstack [option] vmid

option参数:

  • -F: 当正常输出的请求不被响应是,强制输出线程 堆栈
  • -l:除堆栈外,显示关于锁的附加信息
  • -m:如果调用本地方法的话,可以显示C/C++的堆栈

常用示例:

jstack -l 11666 | ``more

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.25-b02 mixed mode):

"Attach Listener" #25525 daemon prio=9 os_prio=0 tid=0x00007fd374002000 nid=0x70e8 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
    - None
......

在JDK1.5中,java.lang.Thread类新增了一个getAllStackTraces()方法用于获取虚拟机中所有线程的StackTraceElement对象。使用这个方法可以通过简单的几行代码完成jstack的大部分功能。

7、JDK的可视化工具

主要常用的有jconsole jvisualvm 相关的具体用法, 各位读者在具体的使用过程中 慢慢摸索就可以了。在这里就不过多的描述。

jvisualvm:

相关文章