jhat查看OOM产生的dump文件

首先试一下java自带的工具查看一下内存溢出时候的堆文件情况:

首先到进入run选项,点击configure

image-20220907205109948

然后执行下面这样一个肯定会出现堆内存溢出的程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package JVMTest;

import java.util.ArrayList;
import java.util.List;

public class HeaPOOM {
static class TestObject{

}
public static void main(String[] args) {
List<TestObject> list=new ArrayList<TestObject>();
while(true){
list.add(new TestObject());
}
}
}

因为配置了-XX:+HeapDumpOnOutOfMemoryError,所以在OOM的时候会自动生成Dump文件。

执行之后出现下面的提示,也显示了本次的dump文件名。

image-20220907205250592

利用jhat命令可以查看对内存信息:

image-20220907205308543

浏览器访问本地7000端口进入下面的页面:

image-20220907205324169

其中,Other Queries可以查到自己比较想了解的东西。比如下面就可以看看用户自定义类的内存占用情况,这里可以看到,用户自定义的TestObject数量很多,那么基本就可以定位到问题类。

image-20220907205342945

下面是Show heap histogram显示的堆内存情况,但是TestObject占用的内存数好像不大,这个后续可以继续研究。

image-20220907205359883

image-20220907205414364

本来想做做实验,将堆的大小设置大一些,看下自定义类占用内存情况和系统类占用内存情况的对比,但是用jhat查看dump文件出现以下错误。

image-20220907205429675

这里jhat好像不能查看,网上查看了下,可能是由于dump文件太大了。

懒得下载工具了,就直接用了线上网站的一个在线分析https://heaphero.io/index.jsp,但是网站有点慢,没有上传上去,这个坑下回再补吧。

jstack查看死锁情况

我们设计如下的死锁情况:

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
package JVMTest;

public class DeadLockTest {
static Object resource1=new Object();
static Object resource2=new Object();
public static void main(String[] args) {
new Thread(()->{
synchronized(resource1){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(resource2){
System.out.println(Thread.currentThread() + "get resource2");
}


}
},"thread1").start();

new Thread(()->{
synchronized(resource2){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(resource1){
System.out.println(Thread.currentThread()+"get resource1");
}
}
},"thread2").start();
}
}

因为两个线程都在持有一个资源的同时请求对方的资源,所以产生死锁。

我们首先用jps命令获取进程号:

image-20220907205448540

利用jstack就可以查看具体的线程信息了,系统会直接显示死锁信息:

image-20220907205509330