HeapAnalyzer 是 IBM 的一个用来分析 Java 程序的内存堆使用情况的图形化工具。
IBM HeapAnalyzer怎么用?
IBM HeapAnalyzer,下载之后首先阅读一下readme,这上面详细写了HeapAnalyzer的使用方法。可以在命令行中输入
打开heapdump文件后,我一般点击“Analysis”里的“Tree View”,以树的形式从根节点展示内存对象分配的信息

第一行java.lang.ref.Refenrence这个class及它的76个children占用了67%的已用堆大小(31M/46M),它本身仅占用了76bits。双击java.lang.ref.Refenrence,我们可以看到它所引用的两个子节点。其中一个子节点java.lang.ref.Finalizer后的67%指引我们内存泄漏的问题应该在它的引用上。

接下去你可以逐级展开,或者右键点击“Locate a leak suspect”,让HeapAnalyzer帮你找到泄漏可能发生的地方。泄漏一般发生在那些拥有“超乎寻常多”的引用(子节点)的class上,正是这些创建后没有释放、累积了成千上百的对象,造成了OutOfMemory。右键中的“Go to the largest drop subtrees”也是以此为原理而设的,它的解释为:
“Search for total size drop” will find a size drop between the total size of a parent and the biggest total size of child of the parent.
因为出现泄漏的点,每个子节点占用的内存空间不大,但是巨大的数量会导致父节点占用的total size很大。不过反过来寻找到的点都是泄漏发生的地方这种说法是不成立的,否则也不需要我们来分析了。
如何分析 java heap dump 文件?
如果启动过程中发现控制台有java.lang.OutOfMemoryError出现,可以适当加大上面的数字(800),给予更多的空间。
然后“Open”产生的dump文件,打开画面如下,文件很大的话需要等待一段时间
ibm heapAnalyzer工具在打开时已经进行了基本的分析,上面全部完成后,会出现如下结果:
[-photo didnot display-]
除了显示该要结果外,还生成了一棵树。这个画面先不要关,直到你不再需要这个dump了。
基本术语:
[-photo didnot display-]
然后对上面的界面做一下简单的介绍。
[-photo didnot display-]
每个节点树的大小占总的堆栈大小,如94%,然后是这个类的在内存中的大小,后面5个子对象,注意这个子对象的意思不是继承关系中的子类,而是上面定义的:如果A对象参考B对象,则B对象是A对象的字对象。
然后该工具根据分析结果把可能产生泄漏的对象显示了出来。如下图:
[-photo didnot display-]
分析根据主要是child object和parent object的大小差别程度,如果子对象不大,而父对象超级大,很可能是因为父对象是一个集合类(如数组),包含了大量子对象作为元素。
工具栏:
[-photo didnot display-]
点击分析工具栏的表格图标,显示出下面的统计表格,可以点击栏标题进行排序。各标题意思简单介绍如下:
TotalSize:这个对象,以及这个对象的所有子对象(以及子对象的子对象,也就是从这个对象可以参考到的所有对象)的大小的总和,单位为bits;
Size:这个对象的大小,如第一个56bits = 56/8bytes = 7b;
No.Child:子对象的个数,不包括子对象的子对象;
No.Parent:父对象的个数,不包括父对象的对象;
Name:对象的名称。
Address:对象在heap中的地址。
1.分析结果
1.1大量的以java/util/HashMap$Entry为元素的数组,占据了总堆栈的8%,很高的比例。
1.2大量的java/util/Hashtable$HashtableEntry为元素的数组,占据总堆栈的5%。
1.3里面的数组大量指向java/util/Hashtable$HashtableCacheHashEntry对象。
根据分析,最有嫌疑的对象应该是java/util/HashMap$Entry。
2.其他经验收集:
“Heapdump工具的使用很简单,难点在于找到“内存泄漏的真正原因”,一般需要通过多个heapdump文件的对比才能找到。”
“ObjectInputStream/ObjectOutputStream要注意内存泄漏.reset()”
“因为JDK的问题,如果使用的是:J2RE 5.0 IBM J9 2.3AIX ppc-32 build j9vmap3223-20070201,这个SR4的版本有个问题就是,限定了类加载器可加载的类数量,默认为8192,如果超过此限制,就会抛出 OutOfMemory的错误。”
对于这个问题,可以设置增加类加载器可加载的类数量解决。
3.知识补充介绍
3.1堆(Heap)和非堆(Non-heap)内存
按照官方的说法:“Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在Java虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的,所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。
3.2堆内存分配
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC后调整堆的大小。
33非堆内存分配
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
3.4JVM内存限制(最大值)
首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G -2G,Linux系统下为2G -3G),而64bit以上的处理器就不会有限制了。







![[tc]魔兽3 内存修改器](https://p.e5n.com/up/2011-2/2011225163530.jpg)














大小: 8KB
大小: 89.5M
终端仿真器 SecureCRTv7.1.1.264 最新版
串口调试小助手1.3 免费版
WinHex 十六进制编辑器v20.2 SR-5 绿色中文注册版
小旋风ASP服务器安装版
16进制转换工具V1.0 中文绿色版
Adobe AIRV33.1.1.932 官方最新版
github离线安装包64位版V2.9.11官方最新版(github desktop)
mysql数据库.net开发驱动(mysql connector net )8.0.11 官方最新版
MSDN Library Visual Studio 6.0(VC、VB、VF、VJ)中文版win32开发人员必备
版本控制软件(SourceTree)v3.4.6 官方最新版
Delphi Distillerv1.85绿色版
IBM内存检测工具(IBM Thread and Monitor Dump Analyzer for Java)V4.3.3 绿色版
.NETv3.0 可再发行组件包
一键安装JSP环境安装版
slave4j(基于eclipse插件的java代码生成器)V1.0.0 正式版
Auto DebugProfessional 5.6.5.18 中文绿色版
Understand For C++V1.4.319英文安装版