如何使用yourkit工具分析内存溢出工具问题

YourKit Java Profiler Java剖析工具 9.0.3 正式版
温馨提示:您的IP是
投诉建议:
千万流量共享 百度高权重排名
9.0.3 正式版
高速下载:
本地下载:
聚超值推荐
最新游戏推荐
软件专题排行
同类软件下载排行
热门关键词一次使用Eclipse Memory Analyzer分析Tomcat内存溢出
我的图书馆
一次使用Eclipse Memory Analyzer分析Tomcat内存溢出
前言在平时开发、测试过程中、甚至是生产环境中,有时会遇到OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题。我们需要找造成OutOfMemoryError原因。一般有两种情况:
1、内存泄露,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄露的代码位置和原因,才好确定解决方案;2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的情况。以上是处理Java堆问题的思路,具体是怎么进行分析,这里介绍的是使用Eclipse Memory Analyzer tool(MAT)工具分析的过程。
生成dump文件&&&& 通过jvm参数--XX:-HeapDumpOnOutOfMemoryError可以让JVM在出现内存溢出是Dump出当前的内存转储快照;&&&& 或者,用jmap生产dump文件,win通过任务管理器查看tomcat的进程pid,linux用ps命令查看进程pid,然后用jmap命令(Java5:jmap -heap:format=b &pid&;Java6:jmap -dump:format=b,file=HeapDump.bin &pid&)。&&&&&&&& 我这里使用的是,我一生产环境项目,运行一段时间大概3周的样子,就会报OutOfMemoryError。(ps:这个项目出现这种情况已经有好长一段时间了,我们之前的做法是定期的重启tomcat,没有去分析它的原因。)JDK64位主要参数:-Xmx3078M -Xms3078M -XX:PermSize=1024M -XX:MaxPermSize=1024M,内存还是蛮大的。
MAT安装与介绍&&&& 下载地址:http://www.eclipse.org/mat/downloads.php。&&&& 通过MAT打开dump出来的内存文件,打开后如下图:
& & &&&&& 从上图可以看到它的大部分功能。&&&& 1. Histogram可以列出内存中的对象,对象的个数以及大小。&&&& 2. Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。&&&& 3.Top consumers通过图形列出最大的object。&&&& 4.Leak Suspects通过MA自动分析泄漏的原因。
& & &Histogram如下图:
& & &Objects:类的对象的数量。
& & &Shallow size:就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。
&&&& Retained size:是该对象自己的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained size是该对象被GC之后所能回收到内存的总和。
&&&&&我们发现ThreadLocal和bingo.persister.dao.Daos类的对象占用了很多空间。
& & &Dominator Tree如下图:
& & &我们发现quartz的定时器的工作线程(10个)占了很多的内存空间
& & &Top consumers如下图:
& & &这里显示了内存中最大的对象有哪些,他们对应的类是哪些,类加载器classloader是哪些。
& & &有些时候,我们在这里就可以看到代码泄露的位置。
& & &Leak Suspects如下图:
& & &从那个饼图,该图深色区域被怀疑有内存泄漏,可以发现整个heap才250M内存,深色区域就占了34%。后面的描述,告诉我们quartz线程占用了大量内存,并指出system class loader加载的"java.lang.ThreadLocal"实例的内存中聚集(消耗空间),并建议用关键字"java.lang.ThreadLocal$ThreadLocalMap$Entry[]"进行检查。所以,MAT通过简单的报告就说明了问题所在。
通过Leak Suspects的Problem Suspect 1点击【Details ?】,
如下图如下图所示的上下文菜单中选择 List objects -& with outgoning references, 查看ThreadLocal都应用了些什么对象。
现在看到ThreadLocal中引用的对象如下图:
ps:该dao对象包含一个轻量级的ORM关系内容,所以Retained size比较大。
下面继续查看dao的gc ROOT
如下图所示的上下文菜单中选择 Path To GC Roots -& exclude weak references, 过滤掉弱引用,因为在这里弱引用不是引起问题的关键。
从下图中,可以看到在org.quartz.simpl.SimpleThreadPool中保存了daos的引用。所以可以得出是是因为定时器在运行的过程中持有大量的Daos对象应起了内存泄露。为什么会有那么多的Daos呢,Daos不是一个无状态的单例的、可以重用的吗?继续查看spring配置文件发现Daos的bean配置成scope="prototype",导致定时任务又是每次调用都生产新的Daos实例。由于是Daos是无状态的,修改为单例的,问题解决。
以上是通过MAT分析Tomcat应用程序,找到内存泄露的原因,并解决。
TA的最新馆藏[转]&
喜欢该文的人也喜欢1196人阅读
面试(21)
在一次解决系统tomcat老是内存撑到头,然后崩溃的问题时,使用到了jmap。
1 使用命令
在环境是linux+jdk1.5以上,这个工具是自带的,路径在JDK_HOME/bin/下
jmap -histo pid&a.log
2 输出结果摘要
Size&&&&Count&&&Class description
-------------------------------------------------------
&&&&&&&9652324 char[]
&&&&&&&9612963 java.lang.String
&&&&&&&114865&&byte[]
&&&&&&&&3172004 java.util.Hashtable$Entry
&&&&&&&&3157595 com.test.util.IPSeeker$IPLocation
&&&&&&&&9115&&&&java.util.Hashtable$Entry[]
428&&org.apache.tomcat.util.buf.MessageBytes
89&&&int[]
发现有大量的String和自定义对象com.test.util.IPSeeker$IPLocation存在,检查发现此处果然存在内存溢出。修改程序上线后再次用jmap抓取内存数据:
&&&207163&&byte[]
&&&&354285&&char[]
&&&&53558&&&int[]
&&&&479818&&java.util.HashMap$Entry
08&&&java.util.HashMap$Entry[]
308&&com.test.bean.UnionIPEntry
443&&org.apache.tomcat.util.buf.MessageBytes
120&&java.lang.String
内存溢出问题消除。
注意:这个jmap使用的时候jvm是处在假死状态的,只能在服务瘫痪的时候为了解决问题来使用,否则会造成服务中断。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:46787次
排名:千里之外
原创:50篇
转载:33篇
(2)(2)(7)(7)(1)(1)(1)(3)(15)(4)(4)(2)(1)(1)(1)(4)(3)(5)(4)(1)(1)(1)(3)(9)随笔 - 849&
文章 - 11&评论 - 191&trackbacks - 0
国内私募机构九鼎控股打造APP,来就送&20元现金领取地址:内部邀请码:C8E245J&(不写邀请码,没有现金送)国内私募机构九鼎控股打造,九鼎投资是在全国股份转让系统挂牌的公众公司,股票代码为430719,为&中国PE第一股&,市值超1000亿元。&
------------------------------------------------------------------------------------------------------------------------------------------------------------------
在工作中可能会遇到内存溢出这种灾难性的问题,那么程序肯定是存在问题,找出问题至关重要,上一篇文章讲了jmap命令的使用方法,当然用jmap导出的文件我们也看不懂啊,那就交给memory analyzer(mat)这个工具,让他帮助我们来观察程序的内存分布情况吧。
&&&&MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析。下面来看看要怎么做呢,也许对你有用。官方文档:
造成OutOfMemoryError原因一般有2种:
1、内存泄露,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄露的代码位置和原因,才好确定解决方案;2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的情况。
1.&用jmap生成堆信息
这样在E盘的jmap文件夹里会有一个map.bin的堆信息文件&
2.&将堆信息导入到mat中分析 &&
3. 生成分析报告
&&&&mat可以为我们生成多个报告:
&&&&下面来看看生成的这些数据对我们有什么帮助
&&&&从上图可以看到它的大部分功能,在饼图上,你会发现转储的大小和数量的类,对象和类加载器。正确的下面,饼图给出了一个印象最大的对象转储。移动你的鼠标一片看到对象中的对象的细节检查在左边。下面的Action标签中:
Histogram可以列出内存中的对象,对象的个数以及大小。
Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。
Top consumers通过图形列出最大的object。
Leak Suspects通过MA自动分析泄漏的原因。
Class Name : 类名称,java类名
Objects : 类的对象的数量,这个对象被创建了多少个
Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用
Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和
一般来说,Shallow Heap堆中的对象是它的大小和保留内存大小相同的对象是堆内存的数量时,将释放对象被垃圾收集。保留设置一组主要的对象,例如一个特定类的所有对象,或所有对象的一个特定的类装入器装入的类或者只是一群任意对象,是释放的组对象如果所有对象的主要设置变得难以接近的。保留设置包括这些对象以及所有其他对象只能通过这些对象。保留大小是总堆大小中包含的所有对象的保留。摘自eclipse
关于的详细讲解,建议大家查看,这是个很重要的概念。
这儿借助工具提供的regex正则搜索一下我们自己的类,排序后看看哪些相对是占用比较大的。
左边可以看到类的详细使用,比如所属包,父类是谁,所属的类加载器,内存地址,占用大小和回收情况等
这儿有个工具可以根据自己的需求分组查找,默认根据class分组,类似我们sql里的group by了~~
这里可以看到上面3个选项,分别生成overview、leak suspects、top components数据,但是这儿生成的不是图表,如果要看图表在(Overview)中的Action标签里点击查看。
这个是Overview中的&Heap Dump Overview视图,从工具栏中点开,这是一个全局的内存占用信息
Used heap dump
Number of objects
Number of classes
Number of class loaders
Number of GC roots
JVM version
格林尼治标准时间+0800上午9时20分37秒
Identifier size
E:\jmap\map.bin
File length
108,102,005
Total: 12 entries
然后可以点开SystemProperties和Thread Overview进行查看,我这里就不贴了内容比较多。
Dominator Tree
我们可以看到ibatis占了较多内存
Top consumers
这张图展示的是占用内存比较多的对象的分布,下面是具体的一些类和占用。
按等级分布的类使用情况,其实也就是按使用次数查看,java.lang.Class被排在第一
还有一张图是我们比较关心的,那就是按包名看占用,根据包我们知道哪些公共用的到jar或自己的包占用
这样就可以看到包和包中哪些类的占用比较高。
Leak Suspects
从这份报告,看到该图深色区域被怀疑有内存泄漏,可以发现整个heap只有79.7M内存,深色区域就占了62%。所以,MAT通过简单的报告就说明了项目是有可疑代码的,具体点开详情来找到类,
点击鼠标,在List Objects-& with outgoing references下可以查看该类都引用了什么对象,由此查看是否因为其他对象导致的内存问题。
下面继续查看pool的gc ROOT
如下图所示的上下文菜单中选择 Path To GC Roots -& exclude weak references, 过滤掉弱引用,因为在这里弱引用不是引起问题的关键。
进入查看即可,我这儿的代码没有问题,就不用贴了。
The classloader/component&"org.apache.catalina.loader.WebappClassLoader @ 0xa34cde8"&occupies&19,052,864 (22.80%)&bytes. The memory is accumulated in one instance of&"java.util.HashMap$Entry[]"&loaded by&"&system class loader&".Keywordsjava.util.HashMap$Entry[]org.apache.catalina.loader.WebappClassLoader @ 0xa34cde8
这段话是在工具中提示的,他告诉我们WebappClassLoader占了19,052,864&字节的容量,这是tomcat的类加载器,JDK自带的系统类加载器中占用比较多的是HashMap。这个其实比较正常,大家经常用map作为存储容器。
除了在上一页看到的描述外,还有Shortest Paths To the Accumulation Point和Accumulated Objects部分,这里说明了从GC root到聚集点的最短路径,以及完整的reference chain。观察Accumulated Objects部分,java.util.HashMap的retained heap(size)最大,所以明显类实例都聚集在HashMap中了。
来看看Accumulated Objects by Class区域,这里能找到被聚集的对象实例的类名。java.util.HashMap类上头条了,被实例化了5573次,从这儿看出这个程序不存在什么问题,因为这个数字是比较正常的,但是当出问题的时候我们都会看到比较大的自定义类会在前面,而且占用是相当高。
当然,mat这个工具还有很多的用法,这里把我了解的分享给大家,不管如何,最终我们需要得出系统的内存占用,然后对其进行代码或架构,服务器的优化措施!
参考文献:
阅读(...) 评论()4745人阅读
在平时开发、测试过程中、甚至是生产环境中,有时会遇到OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题。我们需要找造成OutOfMemoryError原因。一般有两种情况:
1、内存泄露,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄露的代码位置和原因,才好确定解决方案;
2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的情况。
以上是处理Java堆问题的思路,具体是怎么进行分析,这里介绍的是使用Eclipse Memory Analyzer tool(MAT)工具分析的过程。
生成dump文件
&&&& 通过jvm参数--XX:-HeapDumpOnOutOfMemoryError可以让JVM在出现内存溢出是Dump出当前的内存转储快照;
&&&& 或者,用jmap生产dump文件,win通过任务管理器查看tomcat的进程pid,linux用ps命令查看进程pid,然后用jmap命令(Java5:jmap -heap:format=b &pid&;Java6:jmap -dump:format=b,file=HeapDump.bin &pid&)。
&&&& 我这里使用的是,我一生产环境项目,运行一段时间大概3周的样子,就会报OutOfMemoryError。(ps:这个项目出现这种情况已经有好长一段时间了,我们之前的做法是定期的重启tomcat,没有去分析它的原因。)JDK64位主要参数:-Xmx3078M -Xms3078M -XX:PermSize=1024M -XX:MaxPermSize=1024M,内存还是蛮大的。
MAT安装与介绍
&&&& 下载地址:http://www.eclipse.org/mat/downloads.php。
&&&& 通过MAT打开dump出来的内存文件,打开后如下图:
&&&& 从上图可以看到它的大部分功能。
&&&& 1. Histogram可以列出内存中的对象,对象的个数以及大小。
&&&& 2. Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。
&&&& 3.Top consumers通过图形列出最大的object。
&&&& 4.Leak Suspects通过MA自动分析泄漏的原因。
&&&& Histogram如下图:
&&&& Objects:类的对象的数量。
&&&& Shallow size:就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变量(不是成员变量的值)的总和。
&&&& Retained size:是该对象自己的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained size是该对象被GC之后所能回收到内存的总和。
&&&& 我们发现ThreadLocal和bingo.persister.dao.Daos类的对象占用了很多空间。
&&&& Dominator Tree如下图:
&&&& 我们发现quartz的定时器的工作线程(10个)占了很多的内存空间
&&&& Top consumers如下图:
&&&& 这里显示了内存中最大的对象有哪些,他们对应的类是哪些,类加载器classloader是哪些。
&&&& 有些时候,我们在这里就可以看到代码泄露的位置。
&&&& Leak Suspects如下图:
&&&& 从那个饼图,该图深色区域被怀疑有内存泄漏,可以发现整个heap才250M内存,深色区域就占了34%。后面的描述,告诉我们quartz线程占用了大量内存,并指出system class loader加载的&java.lang.ThreadLocal&实例的内存中聚集(消耗空间),并建议用关键字&java.lang.ThreadLocal$ThreadLocalMap$Entry[]&进行检查。所以,MAT通过简单的报告就说明了问题所在。
通过Leak Suspects的Problem Suspect 1点击【Details >>】,
如下图如下图所示的上下文菜单中选择 List objects -& with outgoning references, 查看ThreadLocal都应用了些什么对象。
现在看到ThreadLocal中引用的对象如下图:
ps:该dao对象包含一个轻量级的ORM关系内容,所以Retained size比较大。
下面继续查看dao的gc ROOT
如下图所示的上下文菜单中选择 Path To GC Roots -& exclude weak references, 过滤掉弱引用,因为在这里弱引用不是引起问题的关键。
从下图中,可以看到在org.quartz.simpl.SimpleThreadPool中保存了daos的引用。所以可以得出是是因为定时器在运行的过程中持有大量的Daos对象应起了内存泄露。为什么会有那么多的Daos呢,Daos不是一个无状态的单例的、可以重用的吗?继续查看spring配置文件发现Daos的bean配置成scope=&prototype&,导致定时任务又是每次调用都生产新的Daos实例。由于是Daos是无状态的,修改为单例的,问题解决。
以上是通过MAT分析Tomcat应用程序,找到内存泄露的原因,并解决。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:90443次
积分:1045
积分:1045
排名:千里之外
原创:27篇
转载:39篇
(1)(1)(2)(1)(4)(4)(13)(1)(2)(2)(21)(3)(1)(1)(3)(6)

我要回帖

更多关于 内存溢出修复工具 的文章

 

随机推荐