虚拟机图形化工具
Jconsole
JConsole (Java Monitoring and Management Console)是一种基于 JMX 的可视化监视、管理工具,它管理部分的功能是针对 JMXMBean 进行管理,由于 MBean 可以使用代码、中间件服务器的管理控制台或者所有符合 JMX 规范的软件进行访问。
jconsole集成了线程与内存的可视化展示。
Jconsole连接方式
- 本地连接:通过JDK/bin目录下的“jconsole.exe”启动JConsole 后,将自动搜索出本机运行的所有虚拟机进程,不需要用户自己再使用 jps 来查询了。
- 远程连接
# 生成项目jar
mvn install
# scp将jar包进行远程复制
sudo scp /Users/daniel/Desktop/jvm-demo-0.0.1-SNAPSHOT.jar root@172.16.244.151:/usr/local
# 将jar包启动
#nohup代表以守护线程的方式启动
# -Dcom.sun.management.jmxremote.port 开启远程访问JXM端口
nohup java -Xms800m -Xmx800m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxNewSize=512m -Dcom.sun.management.jmxremote.port=9999 -Djava.rmi.server.hostname=192.168.31.220 -Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false -jar /test/jvm-demo-0.0.1-SNAPSHOT.jar &
# 远程连接
远程进程: 192.168.31.220:9999
用户名:root 密码:123
Jconsole内存监控验证

模拟内存增长示例
public class JconsoleMemory {
public byte[] b1 = new byte[1024 * 512];
public static void main(String[] args) throws InterruptedException {
System.out.println("main thread start!");
Thread.sleep(10000); //休眠10秒
allocate(10000);
}
private static void allocate(int n){
List<JconsoleMemory> jconsoleMemoryList = new ArrayList<>();
for (int i = 0; i < n; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e){
e.printStackTrace();
}
jconsoleMemoryList.add(new JconsoleMemory());
}
}
}
Jconsole线程验证


@SpringBootApplication
@EnableAutoConfiguration
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
private static Object lock1 = new Object();
private static Object lock2 = new Object();
class WaitCondition{
boolean isOpen = false;
public void setOpen(){
isOpen = true;
}
}
WaitCondition waitCondition = new WaitCondition();
/**
* 在springboot项目启动的时候所执行的方法
* 在bean加载完但用户线程进来之前执行的方法
*/
@PostConstruct
public void deadLock(){
new Thread(()->{
synchronized (lock1){
try {
System.out.println(Thread.currentThread().getName()+"得到Lock1");
Thread.sleep(3000L);
}catch (Exception e){
e.printStackTrace();
}
synchronized (lock2){
System.out.println(Thread.currentThread().getName()+"得到Lock2");
}
}
},"线程1").start();
new Thread(()->{
synchronized (lock2){
try {
System.out.println(Thread.currentThread().getName()+"得到Lock2");
Thread.sleep(3000L);
}catch (Exception e){
e.printStackTrace();
}
synchronized (lock1){
System.out.println(Thread.currentThread().getName()+"得到Lock1");
}
}
},"线程2").start();
new Thread(()->{
synchronized (waitCondition){
while (!waitCondition.isOpen){
try {
waitCondition.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"线程3").start();
new Thread(()->{
synchronized (waitCondition){
while (!waitCondition.isOpen){
try {
waitCondition.wait(1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"线程4").start();
}
}
VisualVM
VisualVM是一个集成命令行JDK工具和轻量级分析功能的可视化工具。

VisualVM整合IDEA
# 安装插件
搜索visualvm
# 点击配置VisualVM executable执行路径
setting搜索visualvm
F:/Development/JDK1.8/bin/jvisualvm.exe
线程dump
"线程4" #34 prio=5 os_prio=0 tid=0x000000001f26d800 nid=0x3e9c in Object.wait() [0x00000000250cf000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000772319a10> (a com.xdclass.jvm.DemoApplication$WaitCondition)
at com.xdclass.jvm.DemoApplication.lambda$deadLock$3(DemoApplication.java:83)
- locked <0x0000000772319a10> (a com.xdclass.jvm.DemoApplication$WaitCondition)
at com.xdclass.jvm.DemoApplication$$Lambda$299/1687627235.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"线程3" #33 prio=5 os_prio=0 tid=0x0000000023996800 nid=0x9c in Object.wait() [0x0000000024fcf000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x0000000772319a10> (a com.xdclass.jvm.DemoApplication$WaitCondition)
at java.lang.Object.wait(Object.java:502)
at com.xdclass.jvm.DemoApplication.lambda$deadLock$2(DemoApplication.java:70)
- locked <0x0000000772319a10> (a com.xdclass.jvm.DemoApplication$WaitCondition)
at com.xdclass.jvm.DemoApplication$$Lambda$298/1971152916.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None