Eclipse Memory Analyzee Java内存分析工具安装教程和使用

来源:互联网 发布:java方法中布尔型变量 编辑:程序博客网 时间:2024/05/21 17:57

这里,内存映像工具利用的是Eclipse Memory Analyzee,对Dump出来的堆转存储快照进行分析,可以分清楚到底是出现了内存泄露(Memory Leak)还是内存溢出(Memory Overflow)。

在Eclipse中离线安装MemoryAnalyzee的步骤如下(由于在线安装可能会有网络问题):

(1)去官网下载离线安装包:


即下载MemoyAnalyzer-1.6.1.201611251412.zip包。

(2)下载之后解压得到如下文件内容:


(3)打开Eclipse->Help->Install new Software,如下:


将干菜下载好的路径引入其中。点击Ok。

(4)点击Avaliable Software Sites


注意:将里面,所有有关http连接的去掉勾选,否则,在更新的时候可能失败,如下:


只要location是http开头的就去勾选。

(5)去掉Contact all update sites during install to findrequired software前面的勾


(6)点击next,即可成功安装

那么:Eclipse Memory Analyzer如何使用呢?

为了使用MAT,即Memory Analyzer Tool,这里我们使用的是Eclipse Memory Anaylyzer需要先明白内存分析的数据源是如何产生的。有两种方式:

(1)通过jmap(Memory Map for Java)命令生成堆转储快照(一般称为heapdump或dump文件)

(2)通过JVM参数 -XX:+HeapDumpOnOutOfMemoryError可以让JVM在出现内存溢出异常时Dump出当前内存堆转存储快照以便事后进行分析。

这里先介绍第二种情况,即JVM中内存溢出后能够自动dump出对转存储快照。

编写一个简单的堆溢出的代码如下:

class User{    String name;    String sex;    @Override    public String toString() {        return "User [name=" + name + ", sex=" + sex + "]";    }}public class MemoryLeak1 {    public static void main(String[] args) {        List<User> list = new ArrayList<User>();        while(true){            list.add(new User());        }    }}

分析:上面的代码中,通过List list中不断的添加new User()实例,因为list的作用域是和main方法一样的,而new出来的额User的实例被list中的元素引用,所以,通过while循环new 出来的User不会被GC。因此,导致内存溢出。

为了分析JVM中内存溢出的情况,需要添加JVM的参数:-XX:+HeapDumpOnOutOfMemoryError,操作步骤如下:

点击:Run->DebugConfiguration,在左侧列表下的Java Application下对应的你的Java类,比如:我这里的类是MemoryLeak1,如下:

在Arguments中的VM arguments下填写:-XX:+HeapDumpOnOutOfMemoryError,然后,点击Apply,以及点击Debug,即运行我们之前写的那段会内存溢出的代码。在运行大概两三分钟之后,出现如下异常信息:


可以看到异常信息为java.lang.OutOfMemoryError:Java heap space,即内存溢出异常。上面的黑色字体是将内存堆转储为dump文件,这里的dump文件名称为:java_pid7568.hprof,其中7568是当前Java程序的进程号。

另外,需要注意的是刚才我们生成的dump文件java_pid7568.hprof,这里的路径默认是在项目的根路径下,如果你没有看到该文件,需要强制刷新当前项目,比如:点击项目,然后按F5。


接下来,就是将该dump文件通过我们上面的Memory Analyzer进行分析,步骤如下:

(1)在工具栏上:File->Open File…,选中java_pid7568.hprof文件,并打开


(2)但是产生了如下错误:


点击OK之后,有:


看了上述的问题,大致的意思是说内存溢出错误,后面又说了“Runngin Eclipse”,大致猜测应该是系统给Eclipse软件分配的内存太小,另外,我们查看了java_pid7568.hprof文件的大小为3,355,137KB,大概是3g左右。于是,我们又查看了Eclipse软件下的eclipse.ini文件:


那么eclipse.ini中的参数各是什么意思呢?在理解这些参数之前,需要知道Eclipse这款软件是由java语言开发的,因此,其自身也需要jvm支持的,那么它的默认参数配置就在eclipse.ini中,如下:

-startupplugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar--launcher.libraryplugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.300.v20150602-1417-productorg.eclipse.epp.package.jee.product--launcher.defaultActionopenFile--launcher.XXMaxPermSize512M-showsplashorg.eclipse.platform--launcher.XXMaxPermSize512m--launcher.defaultActionopenFile--launcher.appendVmargs-vmargs-Dosgi.requiredJavaVersion=1.7-Xms512m-Xmx1024m

如上,我们可以看到,Eclipse需要java 1.7版本的支持,一般我们需要安装Jdk环境,假如我们删除掉Jdk环境,那么会出现如下错误:


因此,Eclipse其实本质上就是一个Java程序,我们可以通过JVM自带的jps命令来查看java进程,如下:


我们输入jps发现进程id号为4316,与我们在Windows任务管理器中看到的eclipse对应的PID是一致的,证明了我们说的Eclipse本质上也是一个Java程序。


也需要设置最下的堆大小,这里默认是-Xms512m,最大的堆大小-Xmx1024m,显然最大的堆大小为1024m大概是1G左右,明显小于我们要打开的文件3G的大小,这里,我们将-Xmx设置5120m,如下:

-Dosgi.requiredJavaVersion=1.7-Xms512m-Xmx5120m

再次重启Eclipse,并打开我们之前的那个大概3G左右的dump文件,则可以成功打开。


这里,主要看下“Histogram”,这个会列出每个类的实例个数。以及“Leak Suspects”分析内存可能产生泄露的原因。我们看下:

Histogram:


这里Class Name是对应类型,Objects是对应实例的个数,很明显类com.tim.User的实例个数竟然达到70,091,071个,那么后面跟着的两列:Shallow Heap和Retained Heap是什么东西?

问题:Shallow Heap和Retained Heap 的区别?

ShallowHeap:Shallow中文的意思是肤浅、浅的意思,则Shallow Heap我们可以理解为浅的表面的堆,是对象本身占据的内存的大小,不包含其所引用的对象。

RetainedHeap:Retained中文的意思是保留、保存的意思,则Retained Heap我们可以理解为保留、保存的堆,是当前对象大小+当前对象可直接或者间接引用到的对象的大小总和。

分析:上面的Shallow Heap是比较好理解的,而要真正理解Retained Heap需要先理解GC roots是如何工作的?

GCroots:




阅读全文
0 0
原创粉丝点击