jvisualvm定位JVM内存溢出,死锁,分析GC日志

更新时间:2023-05-17 09:30:26 阅读: 评论:0

jvisualvm定位JVM内存溢出,死锁,分析GC⽇志OOM定位
1. 创造⼀个会OutOfMemoryError的程序
import java.util.LinkedList;
import java.util.List;
public class OutOfMemoryDump {
/**
* JVM 参数
* -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Volumes/mac
*/
public static void main(String[] args){
List<Byte[]> bytes =new LinkedList<>();
while(true){
Byte[] byteNew =new Byte[1024];
bytes.add(byteNew);
}
}
}
运⾏时添加虚拟机运⾏参数:
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Volumes/mac/oomdump.dump 然后可以在/Volumes/mac/中看到有个oomdump.dump的⽂件。
2. 打开jvisualvm⼯具
打开终端,输⼊
jvisualvm
会启动⼀个界⾯,如下
这个界⾯可以查看到当前已经在运⾏的jvm进程。点击左上⾓载⼊,然后选择我们的dump⽂件。
可以看到概要信息,我们出现的错误是OOM,线程是main主线程,然后点“类”按钮,会显⽰出现OOM时的类的信息:
可以很明显的看到有个类占据了95.9%的空间,是java.lang.Byte类,回看我们的代码,在List中不断增加⼤⼩为1024的Byte数组,那么这个地⽅就是引起内存溢出的主要地⽅。
线程死锁定位
1. 模拟⼀个死锁
public class DeadLock {
private static Object lock1 =new Object();
private static Object lock2 =new Object();
public static void main(String[] args){
new Thread(()->{
synchronized(lock1){
System.out.println("第⼀条线程开始运⾏");
try{
Thread.sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();
}
synchronized(lock2){
System.out.println("第⼀条线程开始结束");
}
}
}).start();
new Thread(()->{
synchronized(lock2){
System.out.println("第⼆条线程开始");
try{
Thread.sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();白菜猪肉饺子馅的做法
}
synchronized(lock1){
System.out.println("第⼆条线程结束");
}
}
}).start();
}
}
第⼀条线程持有锁lock1,尝试去获取锁lock2,第⼆条线程持有锁lock2,尝试去获取第⼀条线程的锁lock1,两条线程都持有⾃⼰的锁,想获取对⽅的锁,造成死锁。
2. 打开jvisualvm,左边可以看到我们运⾏的程序:
纸上谈兵右键单击,然后选择线程Dump,可以看到:
翻到最下⾯发现⽇志:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007fcce103bca8 (object 0x000000076af74480, a java.lang.Object),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x00007fcce1037c08 (object 0x000000076af74490, a java.lang.Object),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at stmac.DeadLock.lambda$main$1(DeadLock.java:35)
泰国英语怎么读
-连词有哪些
waiting to lock <0x000000076af74480> (a java.lang.Object)
- locked <0x000000076af74490> (a java.lang.Object)
at stmac.DeadLock$$Lambda$2/1508395126.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"Thread-0":
at stmac.DeadLock.lambda$main$0(DeadLock.java:20)
- waiting to lock <0x000000076af74490> (a java.lang.Object)
- locked <0x000000076af74480> (a java.lang.Object)
at stmac.DeadLock$$Lambda$1/2136344592.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.
夜来花
提⽰发现死锁,继续阅读发现Thread-1持有锁0x000000076af74490,等待锁0x000000076af74480,Thread-0持有锁
0x000000076af74480,等待锁0x000000076af74490,⾄此发现死锁并定位到死锁位置,即at
头像动画1(DeadLock.java:35)和stmac.DeadLock.lambda
stmac.DeadLock.lambda$main
main$0(DeadLock.java:20)就是死锁发⽣的位置。
若是在服务器环境下,并没有图形界⾯,可以使⽤jvisualvm的远程(在左侧侧边栏⾥⾯可以找到)功能,添加远程jvm实时分析,也可以使⽤命令:
梦见旅游是什么意思# jps ⽤来查看当前机器运⾏的jvm进程情况,执⾏后类似如下显⽰
# 689 RemoteMavenServer
# 1105 Launcher
电热水器工作原理
# 674
# 1124 Jps
# 1063 Main
jps
# 然后使⽤命令jstack 进程id > 路径导出线程快照
jstack 1063 > /
# 把 下载到本地进⾏分析即可
GC⽇志查看
在运⾏内存溢出那段代码的时候,GC的⽇志会在控制台输出:
输出⽇志如下:

本文发布于:2023-05-17 09:30:26,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/665943.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:线程   死锁   进程   发现   溢出
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图