eclipse java内存溢出_【JAVA】使用Eclipse Memory Analyzer分析Tomcat内存溢出

本文用MAT(Eclipse Memory Analyzer)分析Tomcat内存溢出原因。

关于如何获取JAVA堆日志可以参考获取JAVA线程和堆信息

MAT安装与介绍

通过MAT打开dump出来的内存文件,打开后如下图:

7678664cc3185212145e935317d9c10b.png

从上图可以看到它的大部分功能。Histogram可以列出内存中的对象,对象的个数以及大小。

Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。

Top consumers通过图形列出最大的object。

Leak Suspects通过MA自动分析泄漏的原因。

Histogram界面

Objects:类的对象的数量。

Shallow

size:就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。

Retained size:是该对象自己的shallow

size,加上从该对象能直接或间接访问到对象的shallow

size之和。换句话说,retained size是该对象被GC之后所能回收到内存的总和。

我们发现ThreadLocal和bingo.persister.dao.Daos类的对象占用了很多空间。

5f5d3212e5f51277fe11b78e576e0d80.png

Dominator Tree界面

我们发现quartz的定时器的工作线程(10个)占了很多的内存空间

94b2a81df0fb6f307db3563a0d17588a.png

Top consumers界面

这里显示了内存中最大的对象有哪些,他们对应的类是哪些,类加载器classloader是哪些。

有些时候,我们在这里就可以看到代码泄露的位置。

2ba7b1821ddd45cda5b187922e604fdf.png

Leak Suspects界面

从那个饼图,该图深色区域被怀疑有内存泄漏,可以发现整个heap才250M内存,深色区域就占了34%。后面的描述,告诉我们quartz线程占用了大量内存,并指出system

class

loader加载的"java.lang.ThreadLocal"实例的内存中聚集(消耗空间),并建议用关键字"java.lang.ThreadLocal$ThreadLocalMap$Entry[]"进行检查。所以,MAT通过简单的报告就说明了问题所在。

703115a56ed70d4a86746f2dd7a72bd1.png

通过Leak Suspects的Problem Suspect 1点击【Details

?】,如下图如下图所示的上下文菜单中选择 List objects -> with outgoning

references, 查看ThreadLocal都应用了些什么对象。

3d543f964ba27b94f65469072eb62610.png

现在看到ThreadLocal中引用的对象如下图:是dao对象

c9b0d3e18ab4b5361ff31783ca148766.png

下面继续查看dao的gc ROOT,如下图所示的上下文菜单中选择 Path To GC Roots

-> exclude weak references,

过滤掉弱引用,因为在这里弱引用不是引起问题的关键。

56eccf47aab46ee161d11a5facef1b0d.png

从下图中,可以看到在org.quartz.simpl.SimpleThreadPool中保存了daos的引用。所以可以得出是是因为定时器在运行的过程中持有大量的Daos对象应起了内存泄露。为什么会有那么多的Daos呢,Daos不是一个无状态的单例的、可以重用的吗?继续查看spring配置文件发现Daos的bean配置成scope="prototype",导致定时任务又是每次调用都生产新的Daos实例。由于是Daos是无状态的,修改为单例的,问题解决。

7a1420df55494950bb8935efe0ee812f.png

以上是通过MAT分析Tomcat应用程序,找到内存泄露的原因,并解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值