- 浏览: 114785 次
- 性别:
- 来自: 武汉
文章分类
- 全部博客 (98)
- java (27)
- jms (2)
- jta (0)
- 性能调优及内存分析 (4)
- 设计模式 (14)
- 框架 (6)
- 其它 (9)
- job (1)
- maven (1)
- 服务器 (2)
- 分布式 (3)
- ibatis (1)
- linux (0)
- mysql (0)
- 并发编程 (0)
- java多线程 (2)
- 前端跨域 (1)
- 线程dump分析 (0)
- velocity (0)
- 数据库 (2)
- 协议 (0)
- 监控 (0)
- 开源软件 (2)
- 算法 (0)
- 网络 (1)
- spring (1)
- 编码 (0)
- 数据结构 (0)
- HTable和HTablePool使用注意事项 (0)
- opencms (0)
- android (16)
- 操作系统 (2)
- top (0)
最新评论
-
hold_on:
@Override public boolea ...
android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片) -
achersnake:
123
Servlet中listener(监听器)和filter的总结 -
angel243fly:
我用了这个方法,还是报同样的错误,还有什么建议吗?
eclipse提示CreateProcess error=87错误的解决方法
http://www.blogjava.net/rosen/archive/2010/06/13/323522.html
写 blog就是好,在大前提下可以想说什么写什么,不像投稿那么字字斟酌。上周末回了趟成都办事,所以本文来迟了。K117从达州经由达成线往成都方向走的 时候,发现铁路边有条河,尽管我现在也不知道其名字,但已被其深深的陶醉。河很宽且水流平缓,河边山丘森林密布,民房星星点点的分布在河边,河里偶尔些小 船。当时我就在想,在这里生活是多么的惬意,夏天还可以下去畅游一番,闲来无事也可垂钓。唉,越来越讨厌北漂了。
前言
在使用Memory Analyzer tool(MAT)分析内存泄漏(一) 中,我介绍了内存泄漏的前因后果。在本文中,将介绍MAT如何根据heap dump分析泄漏根源。由于测试范例可能过于简单,很容易找出问题,但我期待借此举一反三。
一 开始不得不说说ClassLoader,本质上,它的工作就是把磁盘上的类文件读入内存,然后调用 java.lang.ClassLoader.defineClass方法告诉系统把内存镜像处理成合法的字节码。Java提供了抽象类 ClassLoader,所有用户自定义类装载器都实例化自ClassLoader的子类。system class loader在没有指定装载器的情况下默认装载用户类,在Sun Java 1.5中既sun.misc.Launcher$AppClassLoader。更详细的内容请参看下面的资料。
准 备heap dump
请看下面的Pilot类,没啥特殊的。
/**
* Pilot class
* @author rosen jiang
*/
package org.rosenjiang.bo;
public class Pilot{
String name;
int age;
public Pilot(String a, int b){
name = a;
age = b;
}
}
* Pilot class
* @author rosen jiang
*/
package org.rosenjiang.bo;
public class Pilot{
String name;
int age;
public Pilot(String a, int b){
name = a;
age = b;
}
}
然后再看OOMHeapTest类,它是如何撑破heap dump的。
/**
* OOMHeapTest class
* @author rosen jiang
*/
package org.rosenjiang.test;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.rosenjiang.bo.Pilot;
public class OOMHeapTest {
public static void main(String[] args){
oom();
}
private static void oom(){
Map < String, Pilot > map = new HashMap < String, Pilot > ();
Object[] array = new Object[ 1000000 ];
for ( int i = 0 ; i < 1000000 ; i ++ ){
String d = new Date().toString();
Pilot p = new Pilot(d, i);
map.put(i + " rosen jiang " , p);
array[i] = p;
}
}
}
* OOMHeapTest class
* @author rosen jiang
*/
package org.rosenjiang.test;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.rosenjiang.bo.Pilot;
public class OOMHeapTest {
public static void main(String[] args){
oom();
}
private static void oom(){
Map < String, Pilot > map = new HashMap < String, Pilot > ();
Object[] array = new Object[ 1000000 ];
for ( int i = 0 ; i < 1000000 ; i ++ ){
String d = new Date().toString();
Pilot p = new Pilot(d, i);
map.put(i + " rosen jiang " , p);
array[i] = p;
}
}
}
是 的,上面构造了很多的Pilot类实例,向数组和map中放。由于是Strong Ref,GC自然不会回收这些对象,一直放在heap中直到溢出。当然在运行前,先要在Eclipse中配置VM参数 -XX:+HeapDumpOnOutOfMemoryError。好了,一会儿功夫内存溢出,控制台打出如下信息。
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid3600.hprof
Heap dump file created [ 78233961 bytes in 1.995 secs ]
Exception in thread " main " java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid3600.hprof
Heap dump file created [ 78233961 bytes in 1.995 secs ]
Exception in thread " main " java.lang.OutOfMemoryError: Java heap space
java_pid3600.hprof既是heap dump,可以在OOMHeapTest类所在的工程根目录下找到。
MAT安装
话 分两头说,有了heap dump还得安装MAT。可以在http://www.eclipse.org/mat/downloads.php选择合适的方式安装。安装完成后切换 到Memory Analyzer视图。在Eclipse的左上角有Open Heap Dump按钮,按照刚才说的路径找到java_pid3600.hprof文件并打开。解析hprof文件会花些时间,然后会弹出向导,直接Finish 即可。稍后会看到下图所示的界面。
MAT 工具分析了heap dump后在界面上非常直观的展示了一个饼图,该图深色区域被怀疑有内存泄漏,可以发现整个heap才64M内存,深色区域就占了99.5%。接下来是一 个简短的描述,告诉我们main线程占用了大量内存,并且明确指出system class loader加载的"java.lang.Thread"实例有内存聚集,并建议用关键字"java.lang.Thread"进行检查。所以,MAT通 过简单的两句话就说明了问题所在,就算使用者没什么处理内存问题的经验。在下面还有一个"Details"链接,在点开之前不妨考虑一个问题:为何对象实 例会聚集在内存中,为何存活(而未被GC)?是的——Strong Ref,那么再走近一些吧。
点 击了"Details"链接之后,除了在上一页看到的描述外,还有Shortest Paths To the Accumulation Point和Accumulated Objects部分,这里说明了从GC root到聚集点的最短路径,以及完整的reference chain。观察Accumulated Objects部分,java.util.HashMap和java.lang.Object[1000000]实例的retained heap(size)最大,在上一篇文章中我们知道retained heap代表从该类实例沿着reference chain往下所能收集到的其他类实例的shallow heap(size)总和,所以明显类实例都聚集在HashMap和Object数组中了。这里我们发现一个有趣的现象,既Object数组的 shallow heap和retained heap竟然一样,通过Shallow and retained sizes 一 文可知,数组的shallow heap和一般对象(非数组)不同,依赖于数组的长度和里面的元素的类型,对数组求shallow heap,也就是求数组集合内所有对象的shallow heap之和。好,再来看org.rosenjiang.bo.Pilot对象实例的shallow heap为何是16,因为对象头是8字节,成员变量int是4字节、String引用是4字节,故总共16字节。
接 着往下看,来到了Accumulated Objects by Class区域,顾名思义,这里能找到被聚集的对象实例的类名。org.rosenjiang.bo.Pilot类上头条了,被实例化了290,325 次,再返回去看程序,我承认是故意这么干的。还有很多有用的报告可用来协助分析问题,只是本文中的例子太简单,也用不上。以后如有用到,一定撰文详细叙 述。
又是 perm gen
我们在上一篇文章中知道,perm gen是个异类,里面存储了类和方法数据(与class loader有关)以及interned strings(字符串驻留)。在heap dump中没有包含太多的perm gen信息。那么我们就用这些少量的信息来解决问题吧。
看下面的代码,利用interned strings把perm gen撑破了。
/**
* OOMPermTest class
* @author rosen jiang
*/
package org.rosenjiang.test;
public class OOMPermTest {
public static void main(String[] args){
oom();
}
private static void oom(){
Object[] array = new Object[ 10000000 ];
for ( int i = 0 ; i < 10000000 ; i ++ ){
String d = String.valueOf(i).intern();
array[i] = d;
}
}
}
* OOMPermTest class
* @author rosen jiang
*/
package org.rosenjiang.test;
public class OOMPermTest {
public static void main(String[] args){
oom();
}
private static void oom(){
Object[] array = new Object[ 10000000 ];
for ( int i = 0 ; i < 10000000 ; i ++ ){
String d = String.valueOf(i).intern();
array[i] = d;
}
}
}
控 制台打印如下的信息,然后把java_pid1824.hprof文件导入到MAT。其实在MAT里,看到的状况应该和 “OutOfMemoryError: Java heap space”差不多(用了数组),因为heap dump并没有包含interned strings方面的任何信息。只是在这里需要强调,使用intern()方法的时候应该多加注意。
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid1824.hprof
Heap dump file created [ 121273334 bytes in 2.845 secs ]
Exception in thread " main " java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid1824.hprof
Heap dump file created [ 121273334 bytes in 2.845 secs ]
Exception in thread " main " java.lang.OutOfMemoryError: PermGen space
倒 是在思考如何把class loader撑破废了些心思。经过尝试,发现使用ASM来动态生成类才能达到目的。ASM(http://asm.objectweb.org)的主要作 用是处理已编译类(compiled class),能对已编译类进行生成、转换、分析(功能之一是实现动态代理),而且它运行起来足够的快和小巧,文档也全面,实属居家必备之良品。ASM提 供了core API和tree API,前者是基于事件的方式,后者是基于对象的方式,类似于XML的SAX、DOM解析,但是使用tree API性能会有损失。既然下面要用到ASM,这里不得不啰嗦下已编译类的结构,包括:
1、修饰符(例如public、private)、类名、父类名、接口和annotation部分。
2、类成员变量声明,包括每个成员的修饰符、名字、类型和annotation。
3、方法和构造函数描述,包括修饰符、名字、返回和传入参数类型,以及annotation。当然还包括这些方法或构造函数的具体Java字节码。
4、常量池(constant pool)部分,constant pool是一个包含类中出现的数字、字符串、类型常量的数组。
已编译类和原来的类源码区别在于,已编译类只包含类本身,内部类不会在已编译类中出现,而是生成另外一个已编译类文件;其二,已编译类中没有注释;其三,已编译类没有package和import部分。
这 里还得说说已编译类对Java类型的描述,对于原始类型由单个大写字母表示,Z代表boolean、C代表char、B代表byte、S代表short、 I代表int、F代表float、J代表long、D代表double;而对类类型的描述使用内部名(internal name)外加前缀L和后面的分号共同表示来表示,所谓内部名就是带全包路径的表示法,例如String的内部名是java/lang/String;对 于数组类型,使用单方括号加上数据元素类型的方式描述。最后对于方法的描述,用圆括号来表示,如果返回是void用V表示,具体参考下图。
下 面的代码中会使用ASM core API,注意接口ClassVisitor是核心,FieldVisitor、MethodVisitor都是辅助接口。ClassVisitor应该按 照这样的方式来调用:visit visitSource? visitOuterClass? ( visitAnnotation | visitAttribute )*( visitInnerClass | visitField | visitMethod )* visitEnd。就是说visit方法必须首先调用,再调用最多一次的visitSource,再调用最多一次的visitOuterClass方法, 接下来再多次调用visitAnnotation和visitAttribute方法,最后是多次调用visitInnerClass、 visitField和visitMethod方法。调用完后再调用visitEnd方法作为结尾。
注意ClassWriter类,该类实现了ClassVisitor接口,通过toByteArray方法可以把已编译类直接构建成二进制形式。由于我们要动态生成子类,所以这里只对ClassWriter感兴趣。首先是抽象类原型:
/**
* @author rosen jiang
* MyAbsClass class
*/
package org.rosenjiang.test;
public abstract class MyAbsClass {
int LESS = - 1 ;
int EQUAL = 0 ;
int GREATER = 1 ;
abstract int absTo(Object o);
}
* @author rosen jiang
* MyAbsClass class
*/
package org.rosenjiang.test;
public abstract class MyAbsClass {
int LESS = - 1 ;
int EQUAL = 0 ;
int GREATER = 1 ;
abstract int absTo(Object o);
}
其次是自定义类加载器,实在没法,ClassLoader的defineClass方法都是protected的,要加载字节数组形式(因为toByteArray了)的类只有继承一下自己再实现。
/**
* @author rosen jiang
* MyClassLoader class
*/
package org.rosenjiang.test;
public class MyClassLoader extends ClassLoader {
public Class defineClass(String name, byte [] b) {
return defineClass(name, b, 0 , b.length);
}
}
* @author rosen jiang
* MyClassLoader class
*/
package org.rosenjiang.test;
public class MyClassLoader extends ClassLoader {
public Class defineClass(String name, byte [] b) {
return defineClass(name, b, 0 , b.length);
}
}
最后是测试类。
/**
* @author rosen jiang
* OOMPermTest class
*/
package org.rosenjiang.test;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
public class OOMPermTest {
public static void main(String[] args) {
OOMPermTest o = new OOMPermTest();
o.oom();
}
private void oom() {
try {
ClassWriter cw = new ClassWriter( 0 );
cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT,
" org/rosenjiang/test/MyAbsClass " , null , " java/lang/Object " ,
new String[] {});
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, " LESS " , " I " ,
null , new Integer( - 1 )).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, " EQUAL " , " I " ,
null , new Integer( 0 )).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, " GREATER " , " I " ,
null , new Integer( 1 )).visitEnd();
cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, " absTo " ,
" (Ljava/lang/Object;)I " , null , null ).visitEnd();
cw.visitEnd();
byte [] b = cw.toByteArray();
List < ClassLoader > classLoaders = new ArrayList < ClassLoader > ();
while ( true ) {
MyClassLoader classLoader = new MyClassLoader();
classLoader.defineClass( " org.rosenjiang.test.MyAbsClass " , b);
classLoaders.add(classLoader);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
* @author rosen jiang
* OOMPermTest class
*/
package org.rosenjiang.test;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
public class OOMPermTest {
public static void main(String[] args) {
OOMPermTest o = new OOMPermTest();
o.oom();
}
private void oom() {
try {
ClassWriter cw = new ClassWriter( 0 );
cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT,
" org/rosenjiang/test/MyAbsClass " , null , " java/lang/Object " ,
new String[] {});
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, " LESS " , " I " ,
null , new Integer( - 1 )).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, " EQUAL " , " I " ,
null , new Integer( 0 )).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, " GREATER " , " I " ,
null , new Integer( 1 )).visitEnd();
cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, " absTo " ,
" (Ljava/lang/Object;)I " , null , null ).visitEnd();
cw.visitEnd();
byte [] b = cw.toByteArray();
List < ClassLoader > classLoaders = new ArrayList < ClassLoader > ();
while ( true ) {
MyClassLoader classLoader = new MyClassLoader();
classLoader.defineClass( " org.rosenjiang.test.MyAbsClass " , b);
classLoaders.add(classLoader);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
不一会儿,控制台就报错了。
java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid3023.hprof
Heap dump file created [ 92593641 bytes in 2.405 secs ]
Exception in thread " main " java.lang.OutOfMemoryError: PermGen space
Dumping heap to java_pid3023.hprof
Heap dump file created [ 92593641 bytes in 2.405 secs ]
Exception in thread " main " java.lang.OutOfMemoryError: PermGen space
打开java_pid3023.hprof文件,注意看下图的Classes: 88.1k和Class Loader: 87.7k部分,从这点可看出class loader加载了大量的类。
更 进一步分析,点击上图中红框线圈起来的按钮,选择Java Basics——Class Loader Explorer功能。打开后能看到下图所示的界面,第一列是class loader名字;第二列是class loader已定义类(defined classes)的个数,这里要说一下已定义类和已加载类(loaded classes)了,当需要加载类的时候,相应的class loader会首先把请求委派给父class loader,只有当父class loader加载失败后,该class loader才会自己定义并加载类,这就是Java自己的“双亲委派加载链”结构;第三列是class loader所加载的类的实例数目。
在Class Loader Explorer这里,能发现class loader是否加载了过多的类。另外,还有Duplicate Classes功能,也能协助分析重复加载的类,在此就不再截图了,可以肯定的是MyAbsClass被重复加载了N多次。
最后
其 实MAT工具非常的强大,上面故弄玄虚的范例代码根本用不上MAT的其他分析功能,所以就不再描述了。其实对于OOM不只我列举的两种溢出错误,还有多种 其他错误,但我想说的是,对于perm gen,如果实在找不出问题所在,建议使用JVM的-verbose参数,该参数会在后台打印出日志,可以用来查看哪个class loader加载了什么类,例:“[Loaded org.rosenjiang.test.MyAbsClass from org.rosenjiang.test.MyClassLoader]”。
全文完。
发表评论
-
公钥,私钥和数字签名这样最好理解
2012-12-04 13:01 0一、公钥加密 假设一下,我找了两个数字,一个是1,一个是2 ... -
btrace学习二--btrace一个简单例子
2012-11-09 16:28 0btrace安装好了,就看一些语法吧。可以到btrace的官方 ... -
Java解析XML汇总(DOM/SAX/JDOM/DOM4j/XPath)
2012-10-25 20:27 0【目录】 一、【基础知识——扫盲】 二、【DOM、S ... -
如何在文件末尾写入新数据,适用JavaNIO
2012-07-02 09:29 1723转:http://stoneli88.iteye.com/bl ... -
BTrace使用简介
2012-05-23 16:23 932转:http://rdc.taobao.com/team/ ... -
java初始化顺序
2012-05-14 15:39 0转:http://www.cnblogs.com/miniwi ... -
HTMLDecoder,&#开头的编码换转成中文
2012-05-11 10:06 1147转:http://blog.sina.com.cn/s/blo ... -
类初始化顺序
2012-04-09 17:33 0转:http://www.cnblogs.com/miniwi ... -
Heritrix的eclipse配置启动
2012-04-07 11:46 0转:http://blog.csdn.net/lifesoft ... -
执行Runtime.exec异常: error=12,Cannot allocate memory
2012-03-26 10:03 1285转:http://blog.csdn.net/chifen ... -
使用Memory Analyzer tool(MAT)分析内存泄漏(一)
2012-03-13 08:40 885转: http://www.blogjava.net/ro ... -
Java编程中“为了性能”尽量要做到的一些地方
2012-03-12 12:52 0最近的机器内存又爆满了,除了新增机器内存外,还应该好好revi ... -
Java内存模型
2012-02-23 19:57 0(原本准备把内存模型单独放到某一篇文章的某个章节里面讲解,后来 ... -
Runnable、Callable、Executor、Future关系解读
2012-02-22 10:02 0在再度温习Java5的并发编程的知识点时发现,首要的就是把Ru ... -
HashCode本质
2012-02-22 09:05 01.hashcode是用来查找的, ... -
Java并发--任务执行.
2012-02-17 19:40 0PS: 发到博客的文章竟然发布不到论坛, 所以将文章从博客 ... -
java并发编程-Executor框架
2012-02-17 19:39 0Executor框架是指java 5中引入的一系列并发库中 ... -
Java 并发核心编程
2012-02-17 16:28 0内容涉及: 1、关于java ... -
future使用
2012-02-17 14:53 0在Java中,如果需要设 ... -
常用 Java 静态代码分析工具的分析与比较
2012-02-16 14:20 0转:http://www.ibm.com/develope ...
相关推荐
MAT是分析Java堆内存的一个工具,全称是 The Eclipse Memory Analyzer Tool,用来帮助分析内存泄漏和减少内存消耗。使用MAT分析Java堆快照,可以快速计算出对象的保留大小(Retained Sizes),查找到阻止对象被回收...
MAT 是一个开源的java内存分析工具,能够快速的分析dump文件,可以直观的看到各个对象在内存占用的量大小,以及类实例的数量,对象之间的引用关系,找出对象的GC Roots相关的信息,此外还能生成内存泄露报表,疑似...
Memory Analyzer Tool,简称MAT,是Oracle公司开发的一款强大的Java内存分析工具,专用于诊断和优化Java应用的内存使用情况。MAT独立版为Mac用户提供了在操作系统环境下独立运行的版本,方便开发者对Mac平台上的Java...
内存分析是Java应用程序性能优化的关键环节,而Memory Analyzer Tool (MAT) 是IBM开发的一款强大的内存分析工具,专门用于诊断Java应用程序中的内存泄漏和性能问题。MAT不仅提供了详细的内存使用报告,还能帮助...
MemoryAnalyzer,即MAT(Memory Analyzer Tool),是一款由Eclipse基金会开发的强大的Java内存分析工具,尤其适用于IBM JVM(openj9)上的heap dump文件分析。本文将详细介绍MemoryAnalyzer的特性和功能,以及如何...
MAT(Memory Analyzer Tool)是Eclipse项目开发的一款强大的Java内存分析工具,主要用于诊断Java应用程序的内存泄漏和性能问题。在标题中提到的“Eclipse Memory Analyzer Version 1.7.0.rar”是一个压缩包,其中...
《MemoryAnalyzer:深入理解Java内存分析工具》 在Java编程领域,内存管理是优化应用程序性能的关键环节。Java的垃圾回收机制虽然在很大程度上减轻了程序员对内存管理的负担,但仍然存在内存泄漏和性能瓶颈等问题。...
MemoryAnalyzer,简称MAT,是IBM公司开发的一款强大的Java内存分析工具,尤其在处理Android应用的内存泄漏问题时,MAT显得尤为关键。本文将深入探讨MAT的功能、使用方法以及如何通过它来定位和解决Android应用中的...
### Eclipse Memory Analyzer (MAT) 分析 Tomcat 内存溢出详解 #### 一、引言 在软件开发过程中,特别是在 Java 应用程序中,内存管理是非常关键的一环。当应用程序遭遇 `OutOfMemoryError` 异常时,通常意味着...
为了帮助开发者更好地理解和优化Java应用程序的内存使用,Eclipse提供了Memory Analyzer Tool(MAT),一个强大的内存分析工具。本文将详细介绍MAT在Windows 64位系统中的使用,以及如何利用MAT对dump文件进行分析。...
Eclipse Memory Analyzer 是一个功能丰富且轻量的 Java 堆内存分析工具,可以用来辅助发现内存泄漏减 少内存占用。 使用 Memory Analyzer 来分析生产环境的 Java 堆转储文件,可以从数以百万计的对象中快速计算出对 ...
内存分析是Java应用程序性能优化的关键环节,而Memory Analyzer Tool (MAT) 是IBM提供的一款强大的、独立的内存分析工具,它并非作为Eclipse的集成插件存在。MAT的强大之处在于其能够帮助开发者深入理解应用程序的...
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存...
描述中的"java eclipse memory analyzer (MAT) 内存分析工具 64位"进一步明确了MAT的功能和适用平台。MAT是Eclipse项目的一部分,是一个功能丰富的图形化工具,用于检查和理解Java应用的内存消耗。它提供了深入的...
Eclipse Memory Analyzer(MAT,全称Memory Analyzer Tool)是一款强大的Java内存分析工具,尤其在Mac平台上,它提供了独立于Eclipse环境的版本,方便开发者直接使用。MAT的主要目标是帮助开发者诊断和解决Java应用...
MAT(Memory Analyzer Tool)工具是eclipse的一个插件,使用起来非常方便,尤其是在分析大内存的dump文件时,可以非常直观的看到各个对象在堆空间中所占用的内存大小、类实例数量、对象引用关系、利用OQL对象查询,...
Eclipse Memory Analyzer(内存分析器)是一款专门为Java堆内存分析而设计的工具,它可以协助开发者快速地分析内存泄漏问题,通过生成的报告指出潜在的内存泄漏可疑点。Memory Analyzer可以单独使用,也可以作为...