使用Mat分析大堆信息
在定位一线问题时经常碰测试中出现Out Of Memory的问题, 通过jmap查看,发现JVM heap全用满了。有很多工具可以查看JVM堆的信息, 收费的比如JProfiler, YourKit,免费的如Oracle JDK自带的visualvm, jhat和Eclipse MAT。这个应用安装在一台AWS上,没有图形界面, 内存也比较小,想通过VNC远程桌面启动visualvm或者MAT不可能,通过jhat分析dump出来的snapshot(大约4.3G)也很慢,半天没有分析完毕,这种办法也放弃。
最后通过MAT的命令行工具分析了dump出来的snapshot,查找到OOM的元凶。
一、使用脚本分析Dump文件
如果没有办法图形化启动visualvm和MAT,那么就使用MAT文件夹下的ParseHeapDump.sh, 特别适合分析大堆的信息。
首先你需要修改MemoryAnalyzer.ini中的Xmx值,确保有充足的硬盘空间(至少dump文件的两倍)。然后运行:
./ParseHeapDump.sh heap.bin org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components
会得到suspects, overview和top_components三个视图的信息:
可以看到akka.dispatch.Dispatcher$$anon$1一个实例占用了2.4GB的内存,这就是罪魁祸首。这其实是akka dispatcher的mailbox中java.util.concurrent.ConcurrentLinkedQueue,每个Node占用了81M的内存,消息体太大了。
二、编写程序得到所需信息
也可以引 MAT的类,得到heap dump中的信息, 因为MAT使用Eclipse RCP框架, 基于osgi架构,使用起来不太方便,所以你可以别人抽取出来的MAT库,如https://bitbucket.org/joebowbeer/andromat,然后实现一个命令行程序,比如下面的例子就是输出所有的字符串的值:
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.parser.model.PrimitiveArrayImpl;
import org.eclipse.mat.snapshot.ISnapshot;
import org.eclipse.mat.parser.internal.SnapshotFactory;
import org.eclipse.mat.snapshot.model.IClass;
import org.eclipse.mat.snapshot.model.IObject;
import org.eclipse.mat.util.ConsoleProgressListener;
import org.eclipse.mat.util.IProgressListener; import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap; public class Main {
public static void main(String[] args) throws SnapshotException, IOException {
String arg = args[args.length - 1];
String fileName = arg;
IProgressListener listener = new ConsoleProgressListener(System.out);
SnapshotFactory sf = new SnapshotFactory();
ISnapshot snapshot = sf.openSnapshot(new File(fileName),new HashMap<String, String>(), listener);
System.out.println(snapshot.getSnapshotInfo());
System.out.println();
String[] classNames = {"java.lang.String"};
for (String name : classNames) {
Collection<IClass> classes = snapshot.getClassesByName(name, false);
if (classes == null || classes.isEmpty()) {
System.out.println(String.format("Cannot find class %s in heap dump", name));
continue;
}
assert classes.size() == 1;
IClass clazz = classes.iterator().next();
int[] objIds = clazz.getObjectIds();
long minRetainedSize = snapshot.getMinRetainedSize(objIds, listener);
System.out.println(String.format("%s instances = %d, retained size >= %d", clazz.getName(), objIds.length, minRetainedSize));
for (int i = 0; i < objIds.length; i++) {
IObject str = snapshot.getObject(objIds[i]);
String address = Long.toHexString(snapshot.mapIdToAddress(objIds[i]));
PrimitiveArrayImpl chars = (PrimitiveArrayImpl) str.resolveValue("value");
String value = new String((char[]) chars.getValueArray());
System.out.println(String.format("id=%d, address=%s, value=%s", objIds[i], address, value)); }
}
}
}
基本上使用ParseHeapDump.sh
已经得到了我所需要的结果,优化akka actor消息的内容解决了我的问题。
三、mat常见功能的使用
1、Histogram 查询
用的最多的功能是 Histogram,点击 Actions下的 Histogram项将得到 Histogram结果:
它按类名将所有的实例对象列出来,可以点击表头进行排序,在表的第一行可以输入正则表达式来匹配结果 :
在某一项上右键打开菜单选择 list objects ->with incoming refs 将列出该类的实例:
它展示了对象间的引用关系,比如展开后的第一个子项表示这个 HomePage(0x420ca5b0)被 HomePageContainer(0x420c9e40)中的 mHomePage属性所引用.
快速找出某个实例没被释放的原因,可以右健 Path to GC Roots-->exclue all phantom/weak/soft etc. reference :
得到的结果是:
从表中可以看出 PreferenceManager -> … ->HomePage这条线路就引用着这个 HomePage实例。用这个方法可以快速找到某个对象的 GC Root,一个存在 GC Root的对象是不会被 GC回收掉的
关于Histogram 的对比请参见:http://blog.csdn.net/lang_man_xing/article/details/22160849
使用Mat分析大堆信息的更多相关文章
- 在Eclipse中使用MAT分析Android程序内存使用状况(转)
对于Android这种手持设备来说,通常不会带有太大的内存,而且一般用户都是长时间不重启手机,所以编写程序的时候必须要非常小心的使用内存,尽量避免有内存泄露的问题出现.通常分析程序中潜在内存泄露的问题 ...
- 使用Memory Analyzer tool(MAT)分析内存泄漏(二)
转载自:http://www.blogjava.net/rosen/archive/2010/06/13/323522.html 前言的前言 写blog就是好,在大前提下可以想说什么写什么,不像投稿那 ...
- 使用Memory Analyzer tool(MAT)分析内存泄漏
前言的前言 写blog就是好,在大前提下可以想说什么写什么,不像投稿那么字字斟酌.上周末回了趟成都办事,所以本文来迟了.K117从达州经由达成线往成都方向走的时候,发现铁路边有条河,尽管我现在也不知道 ...
- 老李案例分享:MAT分析应用程序服务出现内存溢出过程
老李案例分享:MAT分析应用程序服务出现内存溢出过程 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的loa ...
- 【转】如何使用MAT分析内存泄漏
原文链接:http://www.lightskystreet.com/2015/09/01/mat_usage/ MAT - Memory Analyzer Tool 使用进阶 Sep 1, 2015 ...
- 使用MAT分析内存泄露
使用MAT分析内存泄露 对于大型服务端应用程序来说,有些内存泄露问题很难在测试阶段发现,此时就需要分析JVM Heap Dump文件来找出问题.随着单机内存越来越大,应用heap也开得越来越大,动辄十 ...
- 性能监控 | MAT分析内存泄漏
使用MAT分析内存泄漏(二)八周年重印版 - 知乎 .u-safeAreaInset-top { height: constant(safe-area-inset-top) !important; h ...
- JVM探秘:MAT分析内存溢出
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. MAT是分析Java堆内存的一个工具,全称是 The Eclipse Memory A ...
- 013 - 关于GC root: Native Stack | MAT分析
Question: I have some third library code that I run and after some time I run into OutOfMemoryEr ...
随机推荐
- HDU 4884 TIANKENG’s rice shop (模拟)
TIANKENG's rice shop 题目链接: http://acm.hust.edu.cn/vjudge/contest/123316#problem/J Description TIANKE ...
- POJ3278http://poj.org/problem?id=3278
http://poj.org/problem?id=3278 题目大意: m,n两个数m可+1, -1, *2变成n,需要经过几步 #include<stdio.h> #include&l ...
- thymeleaf中的模板布局
一.包括模板片段: 1:定义和引用片段,我们经常会想要包含在模板片段来自其他模板.常见的用途是页脚.标题.菜单…; 为了做到这一点,Thymeleaf需要我们定义包含可用的片段,我们可以通过使用th: ...
- TextKit学习(三)NSTextStorage,NSLayoutManager,NSTextContainer和UITextView
先上一张图: 这是使用UITextView时用到的iOS7新增加的类:NSTextContainer.NSLayoutManager.NSTextStorage及其相互关系: 这三个新出的类还没有在官 ...
- PHP linux spl_autoload_register区分大小写
一个PHP脚本用到spl_autoload_register,在WINDOWS下运行正常,但在LINUX就include不了,后来发现WINDOWS大小写不敏感,而在LINUX下区分大小写,WINDO ...
- 关于STM32的ST官方的库的一点看法
标题确实很别扭,因为我现在用这个库也很别扭. 在不久之前,一直有个讨论的话题:STM32开发是用库还是用寄存器? 很多人的结论是不需要讨论! 但是,今天我想说下我的看法. 首先,我还是一个菜鸟,对库对 ...
- Codeforces Round #278 (Div. 1) B. Strip multiset维护DP
B. Strip Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/487/problem/B De ...
- HDU 4819 Mosaic 二维线段树
Mosaic Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- SQL SERVER NVARCHAR字段INSERT 中文乱码问题解决
INSERT INTO IPatient ( UID, PatientNo, PatientName, PatientGender, Birthday, BloodType, Country, Nat ...
- delphi TPopupMenu.Popup
procedure TPopupMenu.Popup(X, Y: Integer); 这个点是相对桌面的而不是窗体的 GetCursorPos是鼠标的位置 鼠标动这个点就不一样 v ...