用MAT分析JAVA程序运行时的内存使用情况

Java出现OutOfMemoryError或者发现Java应用程序占用的内存很异常,那么我们一般采用下面的步骤分析:
A. 把Java应用程序使用的heap dump下来
B. 使用Java heap分析工具,找出内存占用超出预期的嫌疑对象
C. 根据情况,分析嫌疑对象和其他对象的引用关系。
D. 分析程序的源代码,找出嫌疑对象数量过多的原因。
以下面的代码为例:
public class TObject {
	 int[] arr = new int[20000];  
}  

public class Test1 {
	private List<TObject> list = new ArrayList<TObject>();

	public void test() {

		int i = 0;
		while (true) {
			try {
				Thread.sleep(100);
				//如果不加上循环限制,大概在循环到380多的时候消耗完32M的heap
				if(i>350){
					continue;
				}
				
				list.add(new TObject());
				i++;
				System.out.println("There are " + i + " objects created");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] aregs) {
		new Test1().test();
	}
}
Java应用程序使用的heap dump下来可以有如下的方法:
1,设置jvm让其在out of memory的时候自动生成dump文件:
例如java -Xms32M -Xmx32M -XX:+HeapDumpOnOutOfMemoryError -cp test.jar com.test.Test1

Ctrl+Break可以产生dump文件
据说JDK6以上的版本就不再支持这个参数了
java -Xms32M -Xmx32M -XX:+HeapDumpOnCtrlBreak -cp test.jar com.test.Test1
可以试试
java -Xms32M -Xmx32M -Xrunhprof:format=b,file=heapdump.hprof -cp test.jar com.test.Test1
不过这两个方法不推荐使用
2,利用jdk自带的工具:
2.1 jconsole
Launch jconsole.exe and invoke operation dumpHeap() on com.sun.management.HotSpotDiagnostic MBean
方法的定义:dumpHeap(String outputFile, boolean live)

2.2 jps和jmap
先运行jps得到java进程的id
C:\Temp\test>jps
8208 Test1
4236
7440 Jps
jmap -dump:file=test2.hprof 8208
可以参考下面的链接得到更多的信息:
http://wiki.eclipse.org/index.php/MemoryAnalyzer#Getting_a_Heap_Dump

Java heap分析工具可以使用MAT
安装MAT的eclipse插件
MAT - http://archive.eclipse.org/mat/1.0/update-site/
用MAT可以分析可疑的内存泄露,如下图,
Shallow Heap的意思是当前对象在heap占用的内存字节
Retained Heap的意思是当前对象所引用的所有对象在heap占用的内存字节

通过上图的分析可以得出如下的结果:
在main线程的com.test.Test1-->java.util.ArrayList->java.lang.Object(ArrayList底层
存放对象用的是数组)-->有大量的com.test.TObject实例。

另外MAT也可以对本机器的JVM直接分析,如下图


另外也可用jhap来做分析:http://blog.csdn.net/kkdelta/article/details/7851467

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。