jhat查看OOM产生的dump文件
首先试一下java自带的工具查看一下内存溢出时候的堆文件情况:
首先到进入run选项,点击configure
然后执行下面这样一个肯定会出现堆内存溢出的程序:
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文件名。
利用jhat命令可以查看对内存信息:
浏览器访问本地7000端口进入下面的页面:
其中,Other Queries可以查到自己比较想了解的东西。比如下面就可以看看用户自定义类的内存占用情况,这里可以看到,用户自定义的TestObject数量很多,那么基本就可以定位到问题类。
下面是Show heap histogram显示的堆内存情况,但是TestObject占用的内存数好像不大,这个后续可以继续研究。
本来想做做实验,将堆的大小设置大一些,看下自定义类占用内存情况和系统类占用内存情况的对比,但是用jhat查看dump文件出现以下错误。
这里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命令获取进程号:
利用jstack就可以查看具体的线程信息了,系统会直接显示死锁信息: