工具总结
命令行工具
bin目录中,JDk为我们提供了强大稳定的工具集合,他们都是lib/tool.jar类库的包装。主要有
jps : 显示所有虚拟机进程,类似Linux的ps
jstat : 收集虚拟机各方面的运行数据
jinfo : 显示虚拟机配置
jmap : 生成内存转储快照,即heapdump文件
jhat : 分析heapdump文件,建立http服务器,供用户查看
jstack : 生成虚拟机的线程快照
可视化工具
JConsole:java监视与管理控制台
VisualVM:官方主推工具,提供监控、性能分析、故障处理。优点:功能强大
JPS
JVM Processs Status Tool,可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine Identifier,LVMID)。LVMID与操作系统的进程ID是一致的。
用法:
jps命令格式:jsp [options] [hostid]
usage: jps [-help]
jps [-q] [-mlvV] [<hostid>]
Definitions:
<hostid>: <hostname>[:<port>]
options:
选项 | 作用 |
---|---|
-q | 只输出LVMID,省略主类的名称 |
-m | 输出虚拟机进程启动时传递给主类main()函数的参数 |
-l | 输出主类的全名,如果进程执行的是jar包,输出Jar路径 |
-v | 输出虚拟机进程启动时JVM参数 |
jstat
jstat(JVM Statistics Monitoring Tool)是用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形界面,只是提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。
jstat命令格式:jstat [option vmid [ interval[s|ms] [count] ] ]
option:
vimd:
如果是本地虚拟机进程,VMID与LVMID是一致的。如果是远程虚拟机进程,那VMID的格式应当是:[protocol:] [//] lvmid [@hostname [:port]/servername]
参数interval和count代表查询间隔和次数,如果省略这两个参数,说明只查询一次。假设需要每250毫秒查询一次进程ID为2764的垃圾收集状况,一共查询20次,那命令应当是:
jstat –gc 2764 250 20
一个例子:
[root@WC01 bin 17:59 #35]$ jstat -gcutil 3850
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 50.00 71.32 42.89 50.56 639 1.727 5 0.327 2.054
S0、S1表示Survivor1、Survivor2,分别使用了0%和50%的空间;
E表示Eden区,使用了71.32%的空间;
O表示老年代Old区,使用了42.89%的空间;
P表示永久代Pernament区,使用了50.56的空间;
YGC表示执行Minor GC的次数,一共执行了639次;
YGCT表示执行Minor GC的总耗时为1.727秒
FGC表示执行Full GC的次数,一共执行了5次;
FGCT表示执行Full GC的总耗时为0.327秒;
GCT表示所有GC总耗时为2.054秒。
JAVA8变化:
Java 8完全移除了永久代(PermGen),Metaspace成为了持久代的继任者。
Metaspace其实由两大部分组成
— Klass Metaspace:用来存klass的,klass就是class文件在jvm里的运行时数据结构
— NoKlass Metaspace:专门来存klass相关的其他的内容,比如method,constantPool等,这块内存是由多块内存组合起来的,所以可以认为是不连续的内存块组成的
jinfo
jinfo(Configuration Info for Java)的作用是实时地查看和调整虚拟机各项参数。
jinfo命令格式:jinfo [option] pid
其中option选项可参考一下描述:
jmap
Java(Memory Map for Java)命令用于生成堆转储快照(一般称为heapdump或dump文件)。如果不使用jmap命令,要想获得Java堆转储快照,还有一些比较“暴力”的手段;
1、通过-XX:+HeapDumpOnOutOfMemoryError参数,可以让虚拟机在OOM异常出现之后自动生成dump文件;
2、通过-XX:HeapDumpOnCtrlBreak参数则可以使用[Ctrl]+[Break]键让虚拟机生成dump文件;
3、可在Linux系统下通过kill -3命令发送进程退出信号“吓唬”一下虚拟机,也能拿到dump文件。
jmap命令格式:jmap [option] vmid
vmid与之前类似
option:
例子:
[root@WC01 dumpfile 18:49 #66]$ jmap -dump:format=b,file=tomcat.bin 3850
Dumping heap to /usr/local/apache-tomcat-6.0.43/logs/dumpfile/tomcat.bin ...
Heap dump file created
jhat
jhat(JVM Heap Analysis Tool)命令与jmap搭配使用,来分析jmap生成的堆转储快照。Jhat内置了一个微型的HTTP/HTML服务器。生产dump文件的分析结果后,可以在浏览器中查看。
$ jhat tomcat.bin
然后打开浏览器 http://localhost:7000/ 就可以看到结果了
jstack
jstack(Stack Trace for Java)命令用于生产虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。线程快照就是当虚拟机内每一条线程正在执行的方法堆栈集合,生产线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致长时间等待等都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者等待着什么资源。
jstack命令格式:jstack [option] vmid
option:
JConsole:Java监视与管理控制台
在jdk目录的bin下打开jconsole.exe即可进入,刚开始是个选择进程的
内存查看样例:
代码:
package com.leo.c04;
import java.util.ArrayList;
import java.util.List;
/**
* -Xms100m -Xmx100m -XX:+UseSerialGC
* Created by LEO on 2017/9/6.
*/
public class MonitoringTest {
/**
* 内存占位符对象,一个OOMObject大约占64K
*/
static class OOMObject {
public byte[] placeholder = new byte[64 * 1024];
}
public static void fillHeap(int num) throws InterruptedException {
List<OOMObject> list = new ArrayList<OOMObject>();
for (int i = 0; i < num; i++) {
// 稍作延时,令监视曲线的变化更加明显
Thread.sleep(50);
list.add(new OOMObject());
}
System.gc();
}
public static void main(String[] args) throws Exception {
fillHeap(1000);
}
}
图示:
线程等待:
代码:
package com.leo.c04;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* Created by LEO on 2017/9/6.
*/
public class ThreadWait {
/**
* 线程死循环演示
*/
public static void createBusyThread() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) // 第41行
;
}
}, "testBusyThread");
thread.start();
}
/**
* 线程锁等待演示
*/
public static void createLockThread(final Object lock) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "testLockThread");
thread.start();
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
br.readLine();
createBusyThread();
br.readLine();
Object obj = new Object();
createLockThread(obj);
}
}
图示:
线程死锁:
代码:
package com.leo.c04;
/**
* Created by LEO on 2017/9/6.
*/
public class ThreadLock {
/**
* 线程死锁等待演示
*/
static class SynAddRunalbe implements Runnable {
int a, b;
public SynAddRunalbe(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public void run() {
synchronized (Integer.valueOf(a)) {
synchronized (Integer.valueOf(b)) {
System.out.println(a + b);
}
}
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(new SynAddRunalbe(1, 2)).start();
new Thread(new SynAddRunalbe(2, 1)).start();
}
}
}
图示:
VisualVM:多合一故障处理工具
VisualVM(ALL-in-One Java Troubleshooting Tool)是到目前为止随JDK发布的功能最强大的运行监控和故障处理程序,并且可以预见在未来的一段时间内都是官方主力发展的虚拟机故障处理工具。VisuaVM是基于NetBean平台开发的,因此它一开始就具备了插件扩展功能的特性,通过插件扩展支持,VisualVM几乎可以做到所欲命令行工具的功能和其它Plugins的无限可能性。
安装插件: