内存溢出工具使用方法培训
instances)。 当系统出现重启应用内存溢出时,通常需要重点查看该页面,检查是否存在类加载异常,无法GC的情况。
MAT常用功能页面介绍
Class Loader Explorer
按下图方式打开Class Loader Explorer页面,查看溢出时系统中存在哪些ClassLoader,每个 ClassLoader加载的类数量(Defined Classes)和类的实例数(No .Of instances)。
WebLogic、Tomcat的Javacore信息存放在控制台的输出信 息中。
WebSphere会在server目录(如 \IBM\WebSphere\AppServer\profiles\ AppSrv01\)下生成 独立的javacore文件。
Javacore可以通过以下方式手动获取:Linux下使用 kill -3 进程号,生成Javacore;Windows下通过选中java运行的命 令窗口,按组合键ctrl+break生成Javacore。
基本分析方法
根据heapdump提供的信息,找到javacore中可能出现 问题的代码段,然后进一步分析代码。
MAT安装
第一步:解压安装包
第二步:修改 MemoryAnalyzer.ini配置文件,将Xmx参数设置的足够大,以便能够打开大的 heapdump。
第三步:运行MemoryAnalyzer.exe 第四步:安装插件。
HeapDump生成比较慢,在文件生成过程中,一定不要杀掉进 程,当文件大小不再变化时,才可以杀毒进程。否则文件生成 的不完整,无法分析。
WebLogic、Tomcat需要在JVM参数中添加XX:+HeapDumpOnOutOfMemoryError,否则在内存溢出时, 是不会自动生成HeapDump的。WebSphere不需要添加该参数, 内存溢出时可自动生成heapdump文件。
实例分析
问题现象描述
某项目多次发生宕机,并生成了Heapdump和Javacore 文件,其本质原因是发生了内存溢出错误导致,需要 尽快找出内存溢出的原因。
实例分析
分析处理过程 Heapdump和Javacore文件进行综合分析,发现如下问题: 1.每次宕机生成的Heapdump中占用内存很大比例的对象都是 TdsResultSet这个对象,例如下图为4月29号的Heapdump:
此两处基类代码一个是jdbc的分页查询,一个是 hibernate的分页查询,从开发人员了解到,分页查询 专门做过改造,改造后的方式是先把所有结果集查询 出来,然后再返回一页的数据。这样就会出现在返回 的结果集非常大的情况下占用大量内存,从而导致内 存溢出错误的发生了。
实例分析
结论: 系统宕机的原因是由于分页查询处理不当导致,无论 是jdbc查询分页还是hibernate查询分页都有性能问题。
内存溢出时,会生成多个HeapDump,通常分析其中一个即可。
WebLogic、Tomcat生成的HeapDump,后缀名为hprof。 WebSphere生成的HeapDump,后缀名为phd。
关于JavaCore
Javacore是Java应用各线程在某一时刻运行的快照。它是一 个文本文件,可以通过文本编辑器或JCA打开。
With OutGoing references
查看被选择对象递归引用了哪些对象
MAT常用功能页面介绍
With inComing references
查看对象被哪些对象递归引用了
MAT常用功能页面介绍
Attributes
选中某个对象,在Attributes窗口,可以查看该对象的value,如 下图所示。当中文不能正常显示的时候,可以将value拷贝、黏 贴到文本文件中,即可正常显示。
MAT和JCA工具使用介绍
工具介绍
IBM Thread and Monitor Dump Analyzer for Java (JCA):分析javacore的工具。
Eclipse Memory Analyzer(MAT):分析heapdump的 工具。
关于HeapDump
HeapDump是特定时间点,java进程的内存快照。它包含了快照 被触发时java对象和类在heap中的情况。
MAT常用功能页面介绍
Dominator_tree 显示堆中Top N对象在堆中的占比。
MAT常用功能页面介绍
Leak Suspects
直接给出了导致内存溢出的嫌疑对象,在概览页面下方,点击【Leak Suspects】链接,进行查看。(注意:工具给出的嫌疑对象有时是不准确的, 需要结合业务综合分析。)
谢谢!
MAT常用功能页面介绍
Duplicate Classes
查看哪些类被classloader重复加载了,在概览页面下方,点击【Duplicate Classes】链接,可以进入该页面。 列表中分别显示了类加载的次数(count),classloader加载的类的数量(Defined Class)和类的实例数(No.of
MAT常用功能页面介绍
Path To GC Roots
当系统存在内存泄露时,右键嫌疑对象,选中【Path To GC Roots】,查看该对象被哪些对象引用, 无法被GC。 “exclude all phantom/weak/soft etc. refences”,仅查看该对象的强引用信息。
MAT常用功能页面介绍
默认情况下,Retained Heap值不显示的,需要点击菜单【Calculate Minimum Retained Size(quick approx.)】\ 【Calculate Precise Retained Size】,才能显示出来。正如菜单显示的,Calculate Minimum Retained Size(quick approx.)能够快速计算,但结果不够精确,而Calculate Precise Retained Size计算的比较精确,但比较慢。通常情况下, 按Calculate Minimum Retained Size(quick approx.)方式下是不能分析WebSphere的.phd文件 的,需要安装dtfj插件
MAT常用功能页面介绍
Overview 用于显示“堆的基本信息”、“堆中Top N对象在堆 中的占比”和“常用功能的快速链接” 。
MAT常用功能页面介绍
Histogram
按类分组显示类的对象总数(Objects)、该类所有对象本身,不包括被引用对象占用的总内存大小(Shallow Heap)、 类对象直接或间接引用的对象占用的总内存大小(Retained Heap)。
实例分析
2.在Javacore文件中查找关键字TdsResultSet,发现 每次的javacore中都有线程在处理该对象,并且处于条 件等待状态,下图抓出了线程的执行代码:
实例分析
实例分析
实例分析
实例分析
从以上四个图可以看到,代码中都执行了查询操作, BaseJDBCDAO.executeSqlPaginate(BaseJDBCDAO.jav a:507)、 BaseDAOImpl.getObjectsPaginate(BaseDAOImpl.java: 867)
如何运行JCA?
在文件存放路径执行 java -jar jca412.jar
JCA_查看线程详情
重点关注:Waiting on condition、 Runnable 状态的线程
JCA_Compare Threads
线程在多个连续的javacore中执行了相同的代码,那么这个线程就有可能是问题 线程了。
实例分析
80%的内存(大概1.7G)都被此对象占用,进一步展开此对 象,可以看到此对象有很多子对象构成,如下图所示:
相同子对象有8万个以上,每个TdsDataObject下面还有174个相同子对象。 通过以上分析可以初步推测,宕机时80%的内存被TdsResultSet占用,此 对象存放的是某个查询的查询结果集,查询结果数量在8万个以上。具体 是什么查询导致占用这么多的内存,需要结合Javacore进一步分析。