Visual VM

作用: 是到目前为止随JDK发布的功能最强大的运行监视和故障处理程序,并且可以遇见在未来一段时间内都是官方主力发展的虚拟机故障处理工具。官方在VisualVM的软件说明中写上了“All-in-One”的描述字样,预示着他除了运行监视、故障处理外,还提供了很多其他方面的功能。如性能分析,VisualVM的性能分析功能甚至比起很多专业的收费的工具都不会逊色多少,而且VisualVM还有一个很大的优点:不需要被监视的程序基于特殊的运行,因此他对应用程序的实际性能的影响很小,使得他可以直接应用在生产环境中。

VisualVM基于NetBeans平台开发,因此他一开始就具备了插件扩展功能的特性,通过插件扩展支持,VisualVM可以做到:

  • 显示虚拟机进程以及进程的配置、环境信息(jps、jinfo)。
  • 监视应用程序的CPU、GC、堆、方法区以及线程的信息(jstat、jstack)。
  • dump以及分析堆转储快照(jmap、jhat)。
  • 方法级的程序运行性能分析,找到被调用最多、运行时间最长的方法。
  • 离线程序快照:收集程序的运行时配置、线程dump、内存dump等信息建立一个快照,可以将快照发送开发者处进行Bug反馈。
  • 其他plugins的无限的可能性……

使用:

1.在控制台输入:jvisualvm执行即可;

2.安装插件:

2.1 从主菜单中选择“工具”>“插件” ;

2.2 在“可用插件”标签中,选中该插件的“安装”复选框。单击“安装” ;

2.3 逐步完成插件安装程序。

代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.util.ArrayList;
import java.util.List;

/*
jvisualvm:内存分析
*/
public class Demo10 {
public static void main(String[] args) throws Exception{
test1();
System.in.read();
}

private static void test1() throws Exception{
List<Student> list = new ArrayList<Student>();
for (int i = 0; i < 100; i++) {
Thread.sleep(1000);
list.add(new Student());
}

}

}

class Student {
private byte[] big = new byte[5 * 1024 * 1024]; //5M
}

进去之后选择需要监视的进程

双击后右侧窗口显示的就是Demo10的相关信息

右边每个标签(概述、监视、线程、抽样器、Profiler)在VisualVM中对应的都是一个插件 VisualGC不是默认的,后来安装的

默认插件:

概述(Overview):

程序的基本信息和启动参数、环境变量等等;

堆Dump 线程Dump 后面会讲 以文件形式把线程的状态保存下来。

监视(Monitor):

用于显示CPU、内存(分为Heap和Metaspace)、类和线程的使用情况或者数量,另外还包括执行垃圾回收和对堆 Dump的快捷功能 ;

堆那里有两个按钮可以选,堆和老年代的使用情况

右上角有两个按钮一个是垃圾回收,一个是堆Dump,点击垃圾回收会手动执行GC,点击堆Dump会将当前堆以文件的形式保存下来。

堆Dump生成文件 点击可看到(概要、类、实例数、0QL控制台)

查看Dump生成的类(包括类所占的百分比、实例数、以及一共占用内存大小与百分比)

在类中选中一个类 譬如 Java.lang.String 右键在实例视图中显示会自动跳到 实例数 标签中

线程(Threads):

详细查看每个线程的运行时间及状态等;

不同颜色显示不同状态的线程

线程Dump:相当于Jstack,讲线程的堆栈信息以文件形式保存起来。

点击线程Dump

抽样器(Sampler):

对CPU和内存进行一段时长的取样,从而对应用程序进行分析 ;

既可以分析内存也可以分析CPU,点击内存会看到每个类所占内存大小、百分比、实例数,如果想看某一瞬间,点击快照。

点击快照

也可分析CPU占用率

Profiler

也可以分析CPU和内存,和抽样器类似,一般用抽样器(会显示年代数)

使用VisualVM检测程序的死锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/*
jvisualvm:线程分析
*/
public class Demo11 {
public static void main(String[] args) throws Exception{
System.in.read();
System.out.println("死锁");
deadLock();
}

private static void deadLock() {
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
new Thread(() -> {
try {
lock1.lock();
Thread.sleep(100);
lock2.lock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "myThread1").start();
new Thread(() -> {
try {
lock2.lock();
Thread.sleep(100);
lock1.lock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "myThread2").start();
}
}

运行程序,启动Visualvm

直接点击生成线程Dump文件

插件Visual GC

(安装方法在我个人博客里面:www.lovekhh.xyz/blog/105)

整个GC过程、可以实时观察垃圾过程,包括GC 次数、时间等 (这个插件还是很值得推荐的)