使用MemoryAnalyzertoolMAT分析内存泄漏

上传人:ni****g 文档编号:507422800 上传时间:2023-04-04 格式:DOCX 页数:14 大小:126.31KB
返回 下载 相关 举报
使用MemoryAnalyzertoolMAT分析内存泄漏_第1页
第1页 / 共14页
使用MemoryAnalyzertoolMAT分析内存泄漏_第2页
第2页 / 共14页
使用MemoryAnalyzertoolMAT分析内存泄漏_第3页
第3页 / 共14页
使用MemoryAnalyzertoolMAT分析内存泄漏_第4页
第4页 / 共14页
使用MemoryAnalyzertoolMAT分析内存泄漏_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《使用MemoryAnalyzertoolMAT分析内存泄漏》由会员分享,可在线阅读,更多相关《使用MemoryAnalyzertoolMAT分析内存泄漏(14页珍藏版)》请在金锄头文库上搜索。

1、使用 Memory Analyzer tool(MAT)分析内存泄漏(一)前言在平时工作过程中,有时会遇到OutOfMemoryError,我们知道遇到Error 一般表明程序存在着 严重问题,可能是灾难性的。所以找出是什么原因造成 OutOfMemoryError 非常重要。现在向 大家引荐Eclipse Memory Analyzer tool(MAT),来化解我们遇到的难题。如未说明,本文均使用 Java 5.0 on Windows XP SP3 环境。为什么用 MAT之前的观点,我认为使用实时 profiling/monitoring 之类的工具,用一种非常实时的方式来分析 哪里存在

2、内存泄漏是很正确的。年初使用了某 profiler 工具测试消息中间件中存在的内存泄 漏,发现在吞吐量很高的时候 profiler 工具自己也无法响应,这让人很头痛。后来了解到这样 的工具本身就要消耗性能,且在某些条件下还发现不了泄漏。所以,分析离线数据就非常重要 了,MAT正是这样一款工具。为何会内存溢出我们知道JVM根据generation(代)来进行GC,根据下图所示,一共被分为young generation(年 轻代)、tenured generation(老年代)、permanent generation(永久代,perm gen), perm gen (或称 Non-Heap非堆

3、)是个异类,稍后会讲到。注意,heap空间不包括perm gen。TenuredEdenSurvivorspacesVirtualVirtualVirtualYoungPerm绝大多数的对象都在 young generation 被分配,也在 young generation 被收回,当 young generation的空间被填满,GC会进行minor collection(次回收),这次回收不涉及到heap中的其 他 generation, minor collection 根据 weak generational hypothesis(弱年代假设)来假设 young generation

4、 中大量的对象都是垃圾需要回收, minor collection 的过程会非常快。 young generation中未被回收的对象被转移到tenured generation,然而tenured generation也会被填 满,最终触发major collection(主回收),这次回收针对整个heap,由于涉及到大量对象,所以 比 minor collection 慢得多。JVM 有三种垃圾回收器,分别是 throughput collector,用来做并行 young generation 回收,由参数-XX:+UseParallelGC 启动; concurrent low pau

5、se collector , 用 来 做 tenured generation 并 发 回 收 , 由 参 数 - XX:+UseConcMarkSweepGC 启动;incremental low pause c o l l e ct o r ,可以认为是默认的垃圾回收器。不建议直接使用某种垃圾回收 器,最好让JVM自己决断,除非自己有足够的把握。Heap中各generation空间是如何划分的?通过JVM的-Xmx=n参数可指定最大heap空间,而- Xms=n则是指定最小heap空间。在JVM初始化的时候,如果最小heap空间小于最大heap 空间的话,如上图所示 JVM会把未用到的空间

6、标注为 Virtual。除了这两个参数还有- XX:MinHeapFreeRatio=n 和 -XX:MaxHeapFreeRatio=n 来分别控制最大、最小的剩余空间与活动对 象之比例。在32位Solaris SPARC操作系统下,默认值如下,在32位windows xp下,默认值 也差不多。参数默认值Min HeapFreeRatio40MaxHeapFreeRatio70-Xms3670k-Xmx64m由于 tenured generation 的 major collection 较慢,所以 tenured generation 空间小于 young generation的话,会造成

7、频繁的 major collection,影响效率。Server JVM 默认的 young generation 和 tenured generation 空间比例为 1:2,也就是说 young generation 的 eden 和 survivor空间之和是整个 heap (当然不包括 perm gen)的三分之一,该比例可以通过- XX:NewRatio=n 参数来控制 ,而 Client JVM 默认的 -XX:NewRatio 是 8。至于调 整 young generation空间大小的NewSize=n和MaxNewSize=n参数就不讲了,请参考后面的资料。young ge

8、neration 中幸存的对象被转移至U tenured generation,但不幸的是 concurrent collector 线程在这里进行major collection,而在回收任务结束前空间被耗尽了,这时将会发生 Full Collections(Full GC),整个应用程序都会停止下来直到回收完成。Full GC是高负载生产环境的噩 梦现在来说说异类perm gen,它是JVM用来存储无法在Java语言级描述的对象,这些对象分别 是类和方法数据(与class loader有关)以及interned strings(字符串驻留)。一般32位OS下 perm gen 默认 64m

9、,可通过参数-XX:MaxPermSize=n 指定,JVM Memory Structure 一文说,对 于这块区域,没有更详细的文献了,神秘。回到问题“为何会内存溢出?”。要回答这个问题又要引出另外一个话题,既什么样的对象GC才会回收?当然是GC发现通过 任何reference chain(引用链)无法访问某个对象的时候,该对象即被回收。名词GC Roots正是 分析这一过程的起点,例如JVM自己确保了对象的可到达性(那么JVM就是GC Roots),所以 GC Roots就是这样在内存中保持对象可到达性的,一旦不可到达,即被回收。通常GC Roots是 一个在current thread

10、(当前线程)的call stack(调用栈)上的对象(例如方法参数和局部变量),或 者是线程自身或者是system class loader(系统类加载器)加载的类以及native code(本地代码)保 留的活动对象。所以 GC Roots 是分析对象为何还存活于内存中的利器。知道了什么样的对象 GC才会回收后,再来学习下对象引用都包含哪些吧。从最强到最弱,不同的引用(可到达性)级别反映了对象的生命周期。 Strong Ref(强引用):通常我们编写的代码都是Strong Ref,于此对应的是强可达 性,只有去掉强可达,对象才被回收。 Soft Ref(软引用):对应软可达性,只要有足够的内

11、存,就一直保持对象,直到发现 内存吃紧且没有Strong Ref时才回收对象。一般可用来实现缓存,通过java .1 ang.ref.SoftReference 类实现。 Weak Ref(弱引用):比Soft Ref更弱,当发现不存在Strong Ref时,立刻回收对象而 不必等到内存吃紧的时候。通过 java.Iang.ref.WeakReference和 java.util.WeakHashMap类实 现。 Phantom Ref(虚引用):根本不会在内存中保持任何对象,你只能使用Phantom Ref 本身。一般用于在进入finalize()方法后进行特殊的清理过程,通过 java.l

12、ang.ref.PhantomReference 实现。有了上面的种种我相信很容易就能把heap和perm gen撑破了吧,是的利用Strong Ref,存储 大量数据,直到heap撑破;利用interned strings (或者class loader加载大量的类)把perm gen 撑破。关于 shallow size、retained sizeShallow size就是对象本身占用内存的大小,不包含对其他对象的引用,也就是对象头加成员变 量(不是成员变量的值)的总和。在32位系统上,对象头占用8字节,int占用4字节,不管 成员变量(对象或数组)是否引用了其他对象(实例)或者赋值为n

13、ull它始终占用4字节。故 此,对于String对象实例来说,它有三个int成员(3*4=12字节)、一个char成员(1*4=4字 节)以及一个对象头(8字节),总共3*4 +1*4+8=24字节。根据这一原则,对String a=”rosen jiang”来说,实例a的shallow size也是24字节(很多人对此有争议,请看官甄别并留言给 我,。Retained size是该对象自己的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained size是该对象被GC之后所能回收到内存的总和。为了更好的理 解retained s

14、ize,不妨看个例子。Vut.jlV把内存中的对象看成下图中的节点,并且对象和对象之间互相引用。这里有一个特殊的节点 GC Roots,正解!这就是reference chain的起点。ubj2ub i 4GC E.-njtS从 obj1 入手,上图中蓝色节点代表仅仅只有通过 obj1 才能直接或间接访问的对象。因为可以 通过 GC Roots 访问,所以左图的 obj3 不是蓝色节点;而在右图却是蓝色,因为它已经被包含 在 retained 集合内。所以对于左图,objl 的 retained size 是 objl、obj2、obj4 的 shallow size 总和;右图的 retai

15、ned size 是 objl、obj2、obj3、obj4 的 shallow size 总和。obj2 的 retained size 可以通过相同的方式 计算。Heap Dumpheap dump 是特定时间点, java 进程的内存快照。有不同的格式来存储这些数据,总的来说包 含了快照被触发时 java 对象和类在 heap 中的情况。由于快照只是一瞬间的事情,所以 heap dump 中无法包含一个对象在何时、何地(哪个方法中)被分配这样的信息。在不同平台和不同java版本有不同的方式获取heap dump,而MAT需要的是HPROF格式的 heap dump 二进制文件。 想无需人

16、工干预的话, 要这样配置 JVM 参数: -XX:- HeapDumpOnOutOfMemoryError,当错误发生时,会自动生成heap dump,在生产环境中,只 有用这种方式。如果你想自己控制什么时候生成heap dump,在Windows+JDK6环境中可利用 JConsole工具,而在Linux或者Mac OS X环境下均可使用JDK5、6自带的jmap工具。当然, 还可以配置JVM参数:-XX:+HeapDumpOnCtrlBreak,也就是在控制台使用Ctrl+Break键来生成 heap dump。由于我是windows+JDK5,所以选择了-XX:-HeapDumpOnOutOfMemoryError这种方 式,更多配置请参考MAT Wiki。使用 Memory Analyzer tool(MA

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号