Java内存分析(2)分析Heap Dump
2012-04-08 16:34
381 查看
在这里,我们借助了Eclipse的Memory Analyzer工具,以便获得智能的便于分析的效果图。先下载安装好工具下载地址。
下面来装备内存素材,从简单的开始。假设有一个类,这个类里面不包含任务其它的信息,空的:
然后是一个Mail函数
运行程序,并用上一篇文章中提及的方式获取一个内存的转储文件。然后运行Eclipse Memory Analyzer Tool(MAT),并用其打开转储文件。
你将看到如下的内容:
这个页面显示出了该转储文件中的一些概要信息,如哪些对象占用的内存比例比较多之类。通过点击这些图片,你可以看到更详细的报告。
但是我们先关注一下内存的组织图(其实没有图,更确切的说是个报表的样式了),点击Histogram按钮(上图中的红色区域)。然后在Class Name一栏中输入"Node”并回车,这样就会显示我们刚才自己定义的类的信息了。
那这些信息说明了些什么?
Objects是指内存中,该类型的对象有多少个
Shallow Heap是指该对象占用了多少内存(字节)。一个对象的引用往往需要32或64比特(bit)(基于不同的平台实现,该值也会不同),整型需要占用4字节,长整型8字节。这些是JVM规范里规定,但不同JVM实现可以按照自己方式来存储数据。另外,基于不同的Heap Dump格式,这些值也可能会有变化,但往往会更加真实地反应出内存的占用量。
Retained Set(保留集)指的是一个对象集合。假定一些对象会由于对象X被垃圾回收(GC)后,也同时需要被GC掉,那么这些对象就属于X的Retained Set。注意,Retained Set是包含X本身的。
Retained Heap是指如果该对象被回收,可以简单地理解为对象的Retained Set中的对象所占用的内存的总和。
好了,我们再来看一下上面的图。cm.demo.mat.Node只有一个对象,占用的内存为16bit(2个字节),其Retained Heap是16(Retained Heap没有自动计算出来,你可以选中某一项,然后右键->Calculate Precise Retained Set)。但是需要注意的是,Shallow Heap的实际值与转储文件的格式相关,同时在转储时,会把这个值进行处理以更好地反应实际的内存占用量。但不管怎么说,这个值始终会是8的倍数,也就是说至少是一个字节。
刚才我们用一个最简单的对象来说明一些术语,现在我们来尝试往这个空的类中慢慢地加入一些东西试试。
加入一个java的primitive int 类型,看看会有什么变化:
再加入一个长整型:
似乎我们每增加一个字段,Node的内存占用量就会增加一个字节。
再换一种方式,假如将primitive的int和long换成java.lang.Integer和java.lang.Long呢,结果会不会是一样?!试试!
NodeObj的Retained Set要远大于Node的,但它们的Shallow Heap却是相同的。那看看NodeObj的Retained Set中有哪些元素呢?【选中NodeObj->右键->Show Retained Set】
原来是因为有Integer和Long的原因。
至此,大家应该对MAT中的基本概念及使用方式有所了解了,后面会继续说明一下MAT的高级用途。
下面来装备内存素材,从简单的开始。假设有一个类,这个类里面不包含任务其它的信息,空的:
public class Node{}
然后是一个Mail函数
public class Main{ public static void main(String[] args){ Node n = new Node(); } }
运行程序,并用上一篇文章中提及的方式获取一个内存的转储文件。然后运行Eclipse Memory Analyzer Tool(MAT),并用其打开转储文件。
你将看到如下的内容:
这个页面显示出了该转储文件中的一些概要信息,如哪些对象占用的内存比例比较多之类。通过点击这些图片,你可以看到更详细的报告。
但是我们先关注一下内存的组织图(其实没有图,更确切的说是个报表的样式了),点击Histogram按钮(上图中的红色区域)。然后在Class Name一栏中输入"Node”并回车,这样就会显示我们刚才自己定义的类的信息了。
那这些信息说明了些什么?
Objects是指内存中,该类型的对象有多少个
Shallow Heap是指该对象占用了多少内存(字节)。一个对象的引用往往需要32或64比特(bit)(基于不同的平台实现,该值也会不同),整型需要占用4字节,长整型8字节。这些是JVM规范里规定,但不同JVM实现可以按照自己方式来存储数据。另外,基于不同的Heap Dump格式,这些值也可能会有变化,但往往会更加真实地反应出内存的占用量。
Retained Set(保留集)指的是一个对象集合。假定一些对象会由于对象X被垃圾回收(GC)后,也同时需要被GC掉,那么这些对象就属于X的Retained Set。注意,Retained Set是包含X本身的。
Retained Heap是指如果该对象被回收,可以简单地理解为对象的Retained Set中的对象所占用的内存的总和。
好了,我们再来看一下上面的图。cm.demo.mat.Node只有一个对象,占用的内存为16bit(2个字节),其Retained Heap是16(Retained Heap没有自动计算出来,你可以选中某一项,然后右键->Calculate Precise Retained Set)。但是需要注意的是,Shallow Heap的实际值与转储文件的格式相关,同时在转储时,会把这个值进行处理以更好地反应实际的内存占用量。但不管怎么说,这个值始终会是8的倍数,也就是说至少是一个字节。
刚才我们用一个最简单的对象来说明一些术语,现在我们来尝试往这个空的类中慢慢地加入一些东西试试。
public class Node{ private int fInt = 0; }
加入一个java的primitive int 类型,看看会有什么变化:
再加入一个长整型:
public class Node{ private int fInt = 0; private long fLong = 0L; }
似乎我们每增加一个字段,Node的内存占用量就会增加一个字节。
再换一种方式,假如将primitive的int和long换成java.lang.Integer和java.lang.Long呢,结果会不会是一样?!试试!
public class NodeObj{ private Integer fInt = 0; private Long fLong = 0L; }
public class Main{ public static void main(String[] args){ Node n = new Node(); NodeObj no = new NodeObj(); } }
NodeObj的Retained Set要远大于Node的,但它们的Shallow Heap却是相同的。那看看NodeObj的Retained Set中有哪些元素呢?【选中NodeObj->右键->Show Retained Set】
原来是因为有Integer和Long的原因。
至此,大家应该对MAT中的基本概念及使用方式有所了解了,后面会继续说明一下MAT的高级用途。
相关文章推荐
- EAS服务器内存溢出、宕机解决方案-Heapdump与JavaCore分析
- javacore文件及heapdump文件分析
- 利用JMAP+MAT分析Java Heap Dump
- javacore文件及heapdump文件分析
- Memory Analyzer (MAT) - Java内存Dump分析工具
- 使用AndroidStudio dump heap,再用 Eclipse MAT插件分析内存泄露
- javacore文件及heapdump文件分析
- 利用Java heap dump查找、分析问题
- Java heap dump触发和分析(转)
- java的heap dump触发和分析[转]
- Heapdump javacore文件分析工具
- Heapdump javacore文件分析工具
- Heapdump javacore文件分析工具
- [转]java线程安全、jstack\线程dump、内存查看分析总结
- javacore-heapdump分析示例
- Java heap dump触发和分析
- Java heap dump触发和分析
- 分析 Java heap dump工具之IBM HeapAnalyzer
- heapdump/javacore分析工具
- java程序性能分析之thread dump和heap dump