JVM学习笔记(十一、JDK分析工具)

目录:

  • JVM常用工具分析
  • jps
  • jstat
  • jmap
  • jstack
  • jconsole
  • jvisualvm

JVM常用工具分析

JDK bin目录下中我们所熟知的工具有java.ext、javac.ext,但还有一些其它的命令行程序,可用于监视虚拟机和故障处理。

工具名称 作用描述
jps.exe JVM进程状态工具(JVM Process Status Tool),用于显示目标系统上JVM的Java进程信息
jstat.exe JVM统计监测工具(JVM Statistics Monitoring Tool),主要用于监测并显示JVM的性能统计信息
jinfo.exe Java配置信息工具(Java Configuration Information),用于打印指定Java进程、核心文件或远程调试服务器的配置信息
jhat.exe Java堆分析工具(Java Heap Analysis Tool),用于分析Java堆内存中的对象信息
jmap.exe Java内存映射工具(Java Memory Map),主要用于打印指定Java进程、核心文件或远程调试服务器的共享对象内存映射或堆内存细节
jstack.exe Java堆栈跟踪工具,主要用于打印指定Java进程、核心文件或远程调试服务器的Java线程的堆栈跟踪信息
jmc.exe Java任务控制工具(Java Mission Control),主要用于JVM的生产时间监测、分析、诊断
jvisualvm.exe JVM监测、故障排除、分析工具,主要以图形化界面的方式提供运行于指定虚拟机的Java应用程序的详细信息
jconsole.exe 图形化用户界面的监测工具,主要用于监测并显示运行于Java平台上的应用程序的性能和资源占用等信息

jps:jps [-q] [-mlv] [<hostid>]

显示正在运行的虚拟机进程,不带参数显示全部JVM进程,指定hostid仅展示指定的进程信息。

  • -q:只显示LVMID,省略主类信息(LVMID:本地虚拟机进程唯一编号)。
  • -l:显示虚拟机启动进程时传递给main()的参数
  • -m:显示类全面,如果是jar包显示jar路径
  • -v:显示虚拟机启动时候的JVM参数

jstat:

显示本地或者远程虚拟机进程中的类装载、 内存、 垃圾收集、 JIT编译等运行数据,是定位虚拟机性能问题的首选工具。

该命令有多个常用参数:

-class

类加载数量、卸载数量、总空间及类装载所耗费的时间。

-compiler

显示JIT编译器编译过的方法、耗时等信息。

-gc

统计Java堆,包括Eden、Survivor、老年代、永久代的容量,已用空间、GC时间等信息。

-gccapacity

显示Java堆各个区域使用到的最大、最小空间。

-gcutil

显示已使用空间占总空间的百分比。

-gccause

垃圾收集统计概述(同-gcutil),附加最近两次垃圾回收事件的原因。

-gcnew

新生代行为统计。

-gcnewcapacity

新生代使用到的最大、最小空间统计。

-gcold

统计老年代GC状况。

-gcoldcapacity

年老代行为统计(同-gcoldcapacity),主要关注使用到的最大、最小空间。

-gcpermcapacity

显示永久代使用到的最大、最小空间(-gcmetacapacity)。

-printcompilation

显示已经被JIT编译的方法。

1、class:监视类装载、卸载数量、总空间以及耗费的时间。

表头信息:

  • Bytes:class字节大小。
  • Unloaded:未加载class的数量。
  • Bytes:未加载class的字节大小。
  • Time:加载时间。

2、compiler:输出JIT编译过的方法数量耗时等。

表头信息:

  • Failed:编译失败数量。
  • Invalid:无效数量。
  • Time:编译耗时。
  • FailedType:失败类型。
  • FailedMethod:失败方法的全限定名。

3、gc:垃圾回收堆的行为统计。

4、gccapacity:同-gc,还会输出Java堆各区域使用到的最大、最小空间。

5、gcutil:同-gc,输出的是已使用空间占总空间的百分比。

6、gccause:垃圾收集统计概述(同-gcutil),附加最近两次垃圾回收事件的原因。

7、gcnew:统计新生代行为信息。

8、gcnewcapacity:新生代与其相应的内存空间的统计。

9、gcold:统计老年代行为。

10、gcoldcapacity:老年代与其相应的内存空间的统计。

11、gcpermcapacity:永久代与其相应内存空间的统计(JDK 1.8及之后的版本,该参数位-gcmetacapacity)。

12、printcompilation:显示hotspot编译方法统计。

表头说明:

  • Compiled:最近编译方法的数量。
  • Type:最近编译方法的编译类型。
  • Size:最近编译方法的字节码数。
  • Method:编译方法的类名和方法名。类名使用"/" 代替 "." 作为空间分隔符。方法名是给出类的方法名。格式和HotSpot - XX:+PrintComplation 选项一致。

jstat英文标头释义:

英文标头:

含义:

NGC

当前新生代容量 (KB)。

NGCMN

新生代最小容量。

NGCMX

新生代最大容量。

S0

幸存区S0当前使用比例。

S0C

当前幸存区S0空间 (KB)。

S0U

第一个幸存区的使用大小。

S0CMX

最大幸存区S0大小 (KB)。

S1

幸存区S1当前使用比例。

S1C

当前幸存区S1大小。

S1U

第二个幸存区的使用大小。

S1CMX

最大幸存区S1大小。

E

Eden区使用比例。

EC

当前Eden空间 (KB)。

EU

Eden区的使用大小。

ECMX

最大Eden区空间 (KB)。

TT

对象在新生代存活的次数Tenuring threshold(提升阈值)。

MTT

对象在新生代存活的最大次数,最大的tenuring threshold。

DSS

期望的幸存区大小,survivor区域大小 (KB)。

PC

Perm大小(JDK1.8之前)。

PU

Perm使用大小(JDK1.8之前)。

PGCMN

Perm占用的最小空间(JDK1.8之前)。

PGCMX

Perm占用的最大空间(JDK1.8之前)。

PGC

Perm空间 (KB)(JDK1.8之前)。

M

元数据区使用比例(JDK1.8之后)。

MC

方法区大小(JDK1.8之后)。

MU

方法区使用大小(JDK1.8之后)。

MCMN

最小元数据容量(JDK1.8之后)。

MCMX

最大元数据容量(JDK1.8之后)。

O

老年代使用比例。

OC

当前年老代的空间 (KB)。

OU

老年代使用大小。

OGC

当前年老代的容量 (KB)。

OGCMN

老年代最小容量。

OGCMX

老年代最大容量。

CCS

压缩使用比例(JDK1.8之后)。

CCSC

压缩类空间大小(JDK1.8之后)。

CCSU

压缩类空间使用大小(JDK1.8之后)。

CCSMN

最小压缩类空间大小(JDK1.8之后)。

CCSMX

最大压缩类空间大小(JDK1.8之后)。

YGC

年轻代垃圾回收次数。

YGCT

年轻代垃圾回收消耗时间。

FGC

老年代垃圾回收次数。

FGCT

老年代垃圾回收消耗时间。

GCT

垃圾回收消耗总时间。

jmap:

用于生成heap dump文件,如果不使用这个命令,还可以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候自动生成dump文件

jmap不仅能生成dump文件,还可以查询finalize执行队列、Java堆和永久代的详细信息,如当前使用率、当前使用的是哪种收集器等。

 1 # 显示堆中对象的统计信息,包括类、有多少个实例,合计容量等
 2 $ jmap -histo hostip
 3 $ jmap -histo:live hostip
 4 
 5 # 生成Java堆快照。格式:-dump:[live, ]format=b, file=<filename>
 6 # live为是否只生成存活的对象
 7 $ jmap -dump:file=hostip.hprof
 8 
 9 # 显示堆详细信息,如使用哪种回收器、参数配置、分代状况等
10 $ jmap -heap hostip
11 
12 # 打印类加载统计信息
13 $ jmap -clstats hostip
14 
15 # 显示在F-Queue中等待Finalizer线程执行finalize方法的对象
16 $ jmap -finalizerinfo hostip

MAT:

MAT(Eclipse Memory Analyzer Tool)是一种快速且功能丰富的Java堆分析器,可帮助你查找内存泄漏并减少内存消耗。

使用MAT可以分析包含数亿个对象的高效堆转储,快速计算对象的大小,查看阻止垃圾收集器收集对象的原因,运行报告并自动提取可疑泄漏。

当我们需要处理hprof文件对象转储文件,分析内存相关问题时,MAT绝对是不二之选。

MAT可以作为一个独立分析工具使用,也可以通过Eclipse下载插件结合使用。

jstack:

 用于生成虚拟机当前时刻的线程快照,以便可以进一步定位线程出现长时间停顿的原因,如线程间死锁、 死循环、 请求外部资源导致的长时间等待等

显示结果信息:

  • prio线程的优先级。
  • tid线程id。
  • nid操作系统映射的线程id。

1、线程状态:

  • 死锁,Deadlock(重点关注)。
  • 执行中,Runnable。
  • 等待资源,Waiting on condition(重点关注)。
  • 等待获取监视器,Waiting on monitor entry(重点关注)。
  • 暂停,Suspended。
  • 对象等待中,Object.wait() 或 TIMED_WAITING。
  • 阻塞,Blocked(重点关注)。
  • 停止,Parked。

2、Waiting on condition:

该状态出现在线程等待某个条件的发生,具体是什么原因,可以结合 stacktrace来分析。

如果发现有大量的线程都在处在 Wait on condition,从线程 stack看, 正等待网络读写,这可能是一个网络瓶颈的征兆。

因为网络阻塞导致线程无法执行,一种情况是网络非常忙,几 乎消耗了所有的带宽,仍然有大量数据等待网络读 写;

另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。

3、Waiting for monitor entry 和 in Object.wait():

Monitor是 Java中用以实现线程之间的互斥与协作的主要手段,它可以看成是对象或者 Class的锁,每一个对象有也仅有一个 monitor。

4、初始化线程:

  • main:主线程,用于执行我们编写的Java程序的main方法
  • Reference Handler:处理引用的线程。它主要用于处理引用对象本身(软引用、弱引用、虚引用)的垃圾回收问题。
  • Finalizer:调用对象的finalize方法的线程,就是垃圾回收的线程
    • JVM在垃圾收集时会将失去引用的对象包装成Finalizer对象(Reference的实现),并放入ReferenceQueue,由Finalizer线程来处理;
    • 最后将该Finalizer对象的引用置为null,由垃圾收集器来回收
  • Attach Listener:负责接收外部的命令的线程
    • 该线程是负责接收到外部的命令,执行该命令,并且把结果返回给发送者。
    • 通常我们会用一些命令去要求JVM给我们一些反馈信息,如:java -version、jmap、 jstack等等。如果该线程在JVM启动的时候没有初始化,那么,则会在用户第一次执行JVM命令时,得到启动。
  • Signal Dispatcher:分发处理发送给JVM信号的线程
    • 前面我们提到第一个Attach Listener线程的职责是接收外部JVM命令,当命令接收成功后,会交给signal dispather线程去进行分发到各个不同的模块处理命令,并且返回处理结果。
    • signal dispather线程也是在第一次接收外部JVM命令时,进行初始化工作。

jconsole:

JDK自带的集多种分析于一体的可视化图形工具

jvisualvm:

JDK自带的集多种分析于一体的可视化图形工具,并可以下载多种插件扩展其监控分析功能。

插件中心地址:https://visualvm.github.io/pluginscenters.html

原文地址:https://www.cnblogs.com/bzfsdr/p/13750199.html