jconsole.exe 是java自带的一个可用来监控内存,线程等信息的可视化小工具
目录
在java安装bin目录下
堆内存监视
准备如下代码,并通过“内存”视图进行查看
public class JconsoleTest {
//定义b1是为了增大类的占用空间,使jconsole的视图变化更明显,这里定义的是128kb
//情况一:
byte[] b1 = new byte[128 * 1024];
//情况二:
// public JconsoleTest() {
// byte[] b1 = new byte[128 * 1024];
// }
public static void main(String[] args) {
try {
//为了在程序执行开始前,有时间打开 jconsole
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
fun(1000);
}
private static void fun(int n) {
List<JconsoleTest> jList = new ArrayList<JconsoleTest>();
for (int i = 0; i < n; i++) {
try {
//程序慢点跑,否则还没打开jconsole,就结束了
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
jList.add(new JconsoleTest());
}
}
}
首先情况一时,由于b1定义在成员变量将会长期存在,所以可以看见 jconsole上表现出来的堆内存使用量是持续增长的
再看情况二,将b1定义到构造方法中,他变成了局部变量,随着构造方法的结束,引用弹栈,堆中的对象会更快被回收(如果这个变量没有人引用)
线程监视
准备如下代码,并通过“线程”视图进行查看
import java.util.Scanner;
public class Test4 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (true){
}
}
}, "while true..........").start();
new Thread(new Runnable() {
@Override
public void run() {
Object o = new Object();
synchronized (o){
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "wait...........").start();
}
}
线程栏分别展示了,线程和状态等信息
检测死锁
死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
创造死锁,验证检测死锁功能,准备如下两个类:
package com.jvm.test1;
public class SynTest implements Runnable {
private Object o1;
private Object o2;
public SynTest(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
@Override
public void run() {
synchronized (o1){
try {
Thread.sleep(2000);//避免程序跑的太快,达不到ab抢占的效果
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2){
}
}
}
}
package com.jvm.test1;
public class Test5 {
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
/**
* 过程描述:
* 首先线程t1和t2第一时间各自拿到a和b并加锁
* t1 >>> a
* t2 >>> b
*
* 两秒过后
* 线程t1试图拿b,t2试图拿a,获取不到一直获取,获取不到一直获取,导致阻塞,变成死锁
*/
new Thread(new SynTest(a, b),"t1").start();
new Thread(new SynTest(b, a),"t2").start();
}
}
代码运行后,打开jconsole,查看线程视图,点击检测死锁按钮
将展示死锁的线程和信息
VM概要信息
实际场景中可以通过这个监控软件,来对应用程序进行一些针对性的问题分析,通过经验判断出问题所在