JDK可视化工具
JConsole Java监视与管理控制台
启动JConsole
通过jdk/bin/下的“jconsole.exe”来启动,启动后将搜索出本机运行的所有虚拟机进程,不需要再使用 jps 来查询。双击进程即可开始监控。
概览页显示的是虚拟机运行时的情况,包括“堆内存使用量”、“线程”、“类”、“CPU使用情况”。
内存监控
“内存”页签相当于可视化的 jstat 命令,用于监视受收集器管理的虚拟机内存(Java堆和永久代)的变化趋势。
package com.wjz.demo; import java.util.ArrayList; import java.util.List; public class OOMObject { // 内存占用,每一个OOMObject对象大约占用64K 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(); } /** * -Xms100M -Xmx100M -XX:+UseSerialGC */ public static void main(String[] args) throws InterruptedException { Thread.sleep(5000); fillHeap(800); } }
线程监控
“线程”页签相当于可视化 jstack 命令。用来监视分析线程停顿的原因。
package com.wjz.demo; public class ThreadMonitoring { // 线程死循环 public static void busyThread() { Thread thread = new Thread(new Runnable() { public void run() { while (true){ } } }, "busyThread"); thread.start(); } // 线程锁等待 public static void lockThread(final Object lock) { Thread thread = new Thread(new Runnable() { public void run() { synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { // } } } }, "lockThread"); thread.start(); } public static void main(String[] args) throws Exception { busyThread(); Object lock = new Object(); lockThread(lock); } }
busyThread线程一直执行空循环,从堆栈跟踪上看到一直停留在ThreadMonitoring.java的8行(while (true) {})处。此时线程为Runnable状态且没有归还线程执行令牌的动作,会在空循环上用尽全部执行时间直到线程切换,消耗较多的CPU资源。
lockThread线程等待着lock对象notify或notifyAll方法出现,此线程处于Waiting状态,在被唤醒前不会被分配执行时间。
监控线程是否发生死锁
package com.wjz.demo; public class DeadLock implements Runnable { int a, b; public DeadLock (int a, int b) { this.a = a; this.b = b; } 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 DeadLock(1, 2)).start(); new Thread(new DeadLock(2, 1)).start(); } } }
VisualVM 运行监视、故障处理、性能分析工具
VisualVM通过安装插件来扩展功能,除了命令工具和JConsole工具具备的功能还能进行方法级的程序运行性能分析,找出调用最多执行时间最长的方法等。
插件下载地址:https://visualvm.github.io/pluginscenters.html