• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于java:JVM结合MAT工具来分析OOM问题

java 搞代码 3年前 (2022-02-14) 25次浏览 已收录 0个评论
文章目录[隐藏]

简略来演示一下OOM的剖析和实战。

间接上代码:

public class Demo4 {

    public static void main(String[] args) {
        List<Dandan> list = new ArrayList<>();
    <i style="color:transparent">来源gaodai$ma#com搞$$代**码网</i>    while (true){
            list.add(new Dandan());
        }
    }
}

class Dandan{

}

JVM参数:

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -Xms10m -Xmx10m -XX:+PrintGCDetails -Xloggc:gc_dandan.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./

运行后的日志:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to ./java_pid22788.hprof ...
Heap dump file created [13244840 bytes in 0.050 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3210)
    at java.util.Arrays.copyOf(Arrays.java:3181)
    at java.util.ArrayList.grow(ArrayList.java:267)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:241)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:233)
    at java.util.ArrayList.add(ArrayList.java:464)
    at com.hailintang.demo.jdk8.gc.oom.Demo4.main(Demo4.java:11)

Process finished with exit code 1

java.lang.OutOfMemoryError: Java heap space

首先,这里明确通知咱们内存泄露的中央是:堆

因为配置了参数:-XX:+HeapDumpOnOutOfMemoryError

会在程序产生OOM的时候,主动生成一个文件:java_pid22788.hprof

命名格局为:java_pid(程序的过程号).hprof

接下来当然是用MAT来剖析:hprof文件

在剖析之前,咱们重点关注什么?

  • 第一,哪些对象占用大量内存。
  • 第二,对象被谁援用。(就是要晓得为什么它无奈开释的意思)
  • 第三,定位到具体哪行代码,进行剖析问题

关上hprof文件,如果想要剖析内存泄露的话,就勾选红色框框。

这里,咱们首先看看那些对象占用大量内存。按红色框框Histogram按钮

第一,哪些对象占用大量内存

进入histogram页面

进来页面后,你一眼就能发现哪个对象占用的内存最多。

比方这里就是显著的class com.hailintang.demo.jdk8.gc.oom.Dandan这个类占用了过多内存。

这里说了,这个Dandan类的对象有360146个。到目前为止,咱们临时确定了Dandan对象占用了大量内存。

第二,对象被谁援用

接下来,咱们看看内存过多的对象是被谁援用。

那这个时候须要用到MAT的dominator-tree:就是用来剖析对象之间的关系的工具。

而后你能够看到哪些线程创立了过多的对象。

比方这里创立过多对象的线程就是main thread

而后你开展这个main thread看看到底创立了什么对象

使得main thread占用这么多内存

点开一看,好家伙

发现是一个java.lang.Object[]数组。

持续开展

发现数组外面全是Dandan对象

说到这里,其实就水落石出了

通过层层开展。main thread线程创立的对象和在histogram界面中占用过多内存的对象Dandan对上了。

第三,定位到具体哪行代码,进行剖析问题

找到援用后,最初一步就是要定位一下具体是哪行代码创立了这么多对象?

这个时候须要另一个视图thread_overview。红圈所示

thread_overview的性能:展现出JVM的所有线程以及每个线程以及线程过后的办法调用栈,还有每个办法创立了哪些对象。

特地阐明一下:栈,后进先出,所以,看图的时候,从下往上看

进入thread_overview界面

找到main thread线程,点开看看

你能够疾速看到Demo4.java:11

这个时候,你还不是特地确定的。须要点开持续看看

能够看到这里确实创立了大量的Dandan对象。

到这里你再联合一下大头菜的代码:

好了,到这里,基本上曾经找到了具体是哪行代码引起的OOM问题。

简略总结一下

总结

咱们的方法论是:

  • 第一,哪些对象占用大量内存。——对应的MAT的histogram
  • 第二,对象被谁援用。(就是要晓得为什么它无奈开释的意思)——对应MAT的dominator-tree
  • 第三,定位到具体哪行代码,进行剖析问题—-对应MAT的Thread-overview

而后,咱们依据方法论,联合MAT工具,一个一个步骤来进行排查。目标是为了找到具体哪行代码引起的OOM问题。

下面这个是一个比较简单的OOM问题。只是一个Demo,目标是为了通知你如何应用MAT来剖析OOM问题。

如果简单一点的我的项目,在第三步中,如果出问题的代码是其余第三方中间件,比方tomcat,jetty,rpc等框架引起的OOM,这个时候,还须要你对这些中间件比拟相熟能力定位问题。如果出问题的代码是业务代码,这个时候,是须要邀请负责该项目标开发工程师来进行定位代码的。

其实,大家齐全能够把MAT这个定位OOM问题的方法论,用到理论工作。

好了,明天的技术分享就到这里。

有问题,欢送留言。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于java:JVM结合MAT工具来分析OOM问题

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址