前面已经讲过了jps和jstat调优工具。今天咱们继续说一下其它4个工具。这些工具都在jdk的bin目录下。java
jinfo
显示虚拟机配置信息,咱们经过jinfo --help能看到相应的参数:
算法
option说明浏览器
no option 输出所有的参数和系统属性服务器
-flag name 输出对应名称的参数jvm
-flag [+|-]name 开启或者关闭对应名称的参数ide
-flag name=value 设定对应名称的参数工具
-flags 输出所有的参数性能
-sysprops
输出系统属性spa
咱们能够先使用jps
找到pid
。操作系统
jinfo pid
会输出一堆相关信息
jinfo -flags pid
用来输出JVM
的所有参数
jinfo -flag name pid
使用该命令,能够查看指定的name为 JVM
参数的值。
如:查看当前 JVM
进程是否开启打印·GC
日志。
一样的可使用
jinfo -flag [+|-]name pid
来开启或者关闭对应名称的参数 。
也可使用
jinfo -sysprops pid
来输出当前 JVM
进行的所有的系统属性
jmap(Java Memory Map)
命令,主要用于打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节。jmap
以生成 java
程序的 dump 文件, 也能够查看堆内对象示例的统计信息、查看ClassLoader
的信息以及 finalizer
队列。
jmap
命令能够得到运行中的JVM
的堆的快照,从而能够离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的建立,检查系统中什么对象最多,各类对象所占内存的大小等等。可使用jmap生成Heap Dump。
Memory = direct memory(直接内存) +JVM memory(MaxPermSize +Xmx)
;
jmap --help
打印辅助信息
option说明
pid
:java进程id,命令ps -ef | grep java
获取,或者jps
工具获取executable:产生核心dump的
java
可执行文件core:须要打印配置信息的核心文件
remote-hostname-or-ip:远程调试的主机名或ip
server-id:可选的惟一id,若是相同的远程主机上运行了多台调试服务器,用此选项参数标识服务器
-dump:[live,]format=b,file=使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.
-finalizerinfo 打印正等候回收的对象的信息.
-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用状况.
-histo[:live]
打印每一个class的实例数目,内存占用,类全名信息.JVM
的内部类名字开头会加上前缀”*”. 若是live子参数加上后,只统计活的对象数量.
-clstats
(取代了在JDK8
以前打印类加载器信息的permstat
)打印classload
和jvm heap
长久层的信息. 包含每一个classloader
的名字,活泼性,地址,父classloader
和加载的class数量。
使用命名查看JVM
的heap信息
jmap -heap pid
输出Java堆详细信息 ;
使用
jmap -histo:live pid
输出堆中对象的相关统计信息。
第一列是序号,
第二列是对象个数,
第三列是对象大小byte,
第四列是class name
使用
jmap -finalizerinfo pid
输出等待终结的对象信息
也可使用
jmap -clstats pid
来输出类加载器信息 。
jstack
命令最大的做用就是用来生成thread dump文件,thread dump文件中记录了某一时刻CPU信息 。
jstack
主要用于生成java
虚拟机当前时刻的线程快照。线程快照是当前java
虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的缘由,如线程间死锁、死循环、请求外部资源致使的长时间等待等。
线程出现停顿的时候经过
jstack
来查看各个线程的调用堆栈,就能够知道没有响应的线程到底在后台作什么事情,或者等待什么资源。若是如今运行的java
程序呈现hung的状态,jstack
是很是有用的。
option书面
-F:当正常输出的请求不被响应时,强制输出线程堆栈。
-l:除堆栈外,会打印出额外的锁信息,在发生死锁时能够用jstack -l pid来观察锁持有状况
-m:若是调用到本地方法的话,能够显示C/C++的堆栈
jstack pid
jstack命令会打印出全部的线程,包括用户本身启动的线程和JVM
后台线程,咱们主要关注的是用户线程;
1"http-nio-8080-exec-8" #26 daemon prio=5 os_prio=0 tid=0x000000005b940000 nid=0x1e2c waiting on condition [0x000000005c0be000] java.lang.Thread.State: WAITING (parking)
http-nio-8080-exec-8
:线程名称daemon 表示线程是不是守护线程
prio 表示咱们为线程设置的优先级
os_prio 表示的对应的操做系统线程的优先级,因为并非全部的操做系统都支持线程优先级,因此可能会出现都置为0的状况
tid 是java中为这个线程的id
nid 是这个线程对应的操做系统本地线程id,每个java线程都有一个对应的操做系统线程
wait on condition表示当前线程处于等待状态,可是并没列出具体缘由
java.lang.Thread.StatC:\Users\Administrator\Desktop\ WAITING (parking) 也是表示的处于等待状态,括号中的内容说明了致使等待的缘由,例如这里的parking说明是由于调用了 LockSupport.park方法致使等待
经常使用命令
1# 查询进程的线程信息 输出到jstatck_13324文件中
2jstack 13324 > jstatck_13324
3# 十进制转换为十六进制
4printf "%x\n" 21742
JVM Heap Analysis Tool
命令是与jmap
搭配使用,用来分析jmap
生成的dump,jhat
内置了一个微型的HTTP/HTML服务器,生成dump的分析结果后,能够在浏览器中查看。在此要注意,通常不会直接在服务器上进行分析,由于jhat是一个耗时而且耗费硬件资源的过程,通常把服务器生成的dump文件复制到本地或其余机器上进行分析。
经常使用方式
1#分析 dump 文件
2jhat -J-Xmx512M dump.phrof
3
4#对比 dump 文件
5jhat -baseline dump2.phrof dump1.phrof
代码案例
1public class JhatTest {
2 public static void main(String[] args) {
3 while(true) {
4 String string = new String("老田");
5 System.out.println(string);
6 }
7 }
8}
运行,使用jps
获取进程pid
再使用jmap -dump:format=b,file=heapDump pid
再到对应heapDump的包目录下执行
jhat heapDump
而后能够经过访问
http://localhost:7000/
通常查看堆异常状况主要看这个两个部分:
Show instance counts for all classes (excluding platform),平台外的全部对象信息。以下图:
Show heap histogram 以树状图形式展现堆状况
具体问题排查的时候,须要结合代码,而后观察是否大量应该被回收的对象在一直被引用或者是否有占用内存特别大的对象没法被回收。