您的位置:首页 > 其它

通过MAT工具查找是什么对象造成了OutOfMemoryError

2017-04-02 16:55 495 查看
本文代码来自《Java虚拟机精讲》——高翔龙.著

注意我们的标题:“是什么对象”而非“是什么原因”——知道是什么对象造成OOM很简单,但是具体的原因却需要自己分析.

在idea中配置要运行的程序的JVM参数

-Xms1024m
-Xmx1024m
-Xmn384m
-XX:+PrintGCApplicationStoppedTime
-XX:+UseParallelOldGC
-XX:+PrintGCDetails
-XX:+HeapDumpOnOutOfMemoryError


代码

public class Solution {
public static void main(String[] args) {
final int _1MB = 1024 * 1024;
byte[] value1 = new byte[_1MB * 100];
byte[] value2 = new byte[_1MB * 100];
byte[] value3 = new byte[_1MB * 100];
byte[] value4 = new byte[_1MB * 500];
byte[] value5 = new byte[_1MB * 100];
}
}


控制台输出GC信息

/**
Outputs
[GC (Allocation Failure) [PSYoungGen: 222494K->744K(344064K)] 222494K->205552K(999424K), 0.1043598 secs] [Times: user=0.13 sys=0.08, real=0.10 secs]

Total time for which application threads were stopped: 0.1045227 seconds, Stopping threads took: 0.0000193 seconds

[GC (Allocation Failure) [PSYoungGen: 103144K->680K(344064K)] 307952K->307888K(999424K), 0.0550654 secs] [Times: user=0.02 sys=0.03, real=0.06 secs]

[GC (Allocation Failure) [PSYoungGen: 680K->664K(344064K)] 307888K->307872K(999424K), 0.0025474 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

[Full GC (Allocation Failure) [PSYoungGen: 664K->0K(344064K)] [ParOldGen: 307208K->307823K(655360K)] 307872K->307823K(999424K), [Metaspace: 3378K->3378K(1056768K)], 0.1301659 secs] [Times: user=0.09 sys=0.00, real=0.13 secs]

[GC (Allocation Failure) [PSYoungGen: 0K->0K(344064K)] 307823K->307823K(999424K), 0.0090197 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(344064K)] [ParOldGen: 307823K->307804K(655360K)] 307823K->307804K(999424K), [Metaspace: 3378K->3378K(1056768K)], 0.0138063 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]

Total time for which application threads were stopped: 0.2110962 seconds, Stopping threads took: 0.0000226 seconds

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid12644.hprof ...
Total time for which application threads were stopped: 3.1456809 seconds, Stopping threads took: 0.0000205 seconds
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Solution.main(Solution.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Heap dump file created [322058893 bytes in 3.151 secs]
Heap
PSYoungGen      total 344064K, used 14511K [0x00000000e8000000, 0x0000000100000000, 0x0000000100000000)
eden space 294912K, 4% used [0x00000000e8000000,0x00000000e8e2bde8,0x00000000fa000000)
from space 49152K, 0% used [0x00000000fd000000,0x00000000fd000000,0x0000000100000000)
to   space 49152K, 0% used [0x00000000fa000000,0x00000000fa000000,0x00000000fd000000)
ParOldGen       total 655360K, used 307804K [0x00000000c0000000, 0x00000000e8000000, 0x00000000e8000000)
object space 655360K, 46% used [0x00000000c0000000,0x00000000d2c973c8,0x00000000e8000000)
Metaspace       used 3410K, capacity 4494K, committed 4864K, reserved 1056768K
class space    used 377K, capacity 386K, committed 512K, reserved 1048576K
*/


具体的GC细节这里不做分析,我们看到

Heap dump file created [322058893 bytes in 3.151 secs]


当发生OOM时自动生成dump文件[也可以通过jmap 命令在程序运行过程中生成]

然后用Memory Analyzer 工具分析dump文件

下载地址:]http://www.eclipse.org/downloads/download.php?file=/mat/1.6.1/rcp/MemoryAnalyzer-1.6.1.20161125-win32.win32.x86_64.zip&mirror_id=1248]

运行MemoryAnalyzer,打开dump文件



在Overview视图中,以饼状图的形式列举了程序内存消耗的一些基本信息,其中每一种不同的饼块代表了不同比例的内存消耗情况。如果要定位到引发OutOfMemory的代码点,我们可以通过Dominator Tree菜单选项来进行排查,如图



在Dominator Tree视图中,内存中所有的对象都会按照内存消耗的排名从高到底进行排序显示,由此可以可见引发OutOfMemory的几个大对象都被标记在了首位。其中“ClassName”项是Java类的全限定名;“Shallow Heap”项和“Retained Heap”项分别指的是对象本身所消耗的内存大小,以及对象本身和它所引用的对象的内存大小总和;而“Percentage”则用于表示对象消耗所占整个dump total的百分比

在上图中,点击位于第一位的Thread,显示如图



Histogram视图



QQL视图

利用QQL对象查询,可以很方便的找出对象GC Roots的相关信息



thread_overview视图

显示线程的名字,栈,栈帧信息,”retained heap”,类加载器等信息



MAT还有许多其它的功能,像找出某个对象与GC Roots的路径,显示安全点等功能,很方便~

假期愉快,谢谢阅读~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐