15.性能优化-工具-MAT

1.MAT概述
MAT是Java堆内存分析工具,可从http://www.eclipse.org/mat/中下载。
MAT分析用的内存dump文件,可以通过jmap -dump:format=b,file=d:/111.dump生成,或者通过配置JVM参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/error.hprof ,这样发生OOM时会自动生成dump文件,也可以在VisualVM中生成,也可以在MAT中连接JVM生成dump文件。
2.深堆(Retained Heap)和浅堆(Shallow Heap)
2.1简单对象大小计算方法
例如对于Class:
public class HeapSizeDemo{
private int i;
}
对于这个class来说,它在32位JVM下,对象头中包含指向方法区Class对象的一个引用占用[color=red][b]4[/b][/color]个字节,还有对象的mark word,mark word包括对象的hashcode,对象的年龄等,占用[color=red][b]4[/b][/color]个字节。(如果是数组的话,还有另外4个字节存储长度)。class的内容包含一个int类型的i,int类型的占用[color=red][b]4[/b][/color]个字节,Java中按8个字节补齐,所以另外还有[color=red][b]4[/b][/color]个补齐的字节,这也是拿空间换时间的一种优化策略,这样这个对象共占用4+4+4+4=16个字节。

类型 占用字节数
byte 1
boolean 1
char 2
short 2
int 4
float 4
long 8
double 8
reference/引用 4 :32位JVM

如果是64位虚拟机,如果未开启指针压缩,那么引用占8个字节,mark work也占8个字节。如果开启了指针压缩,引用占4个字节,mark word仍然占用8个字节。所以在内存紧张的情况下,64位机器性能比32位的差。

对象的大小可以通过Instrument API来统计,各位可以自己在网上查找相关资料。
2.2浅堆和深堆
浅堆是指对象所消耗的内存大小,它只跟对象的结构有关,而跟对象的内容无关,浅堆也不计算引用的实际对象的大小。
深堆包含它所引用的对象的大小,深堆指的是如果这个对象被回收,可以释放的内存空间。

在MAT中的单位是字节。
3 简单示例
3.1 OOM代码
public class HeapOOM {

public static void main(String[] args) throws Exception{
List<String> list = new ArrayList<String>();
while(true) {
list.add("i want oom, quickly");
}
}
}


3.2 整体界面

[img]http://dl2.iteye.com/upload/attachment/0106/5206/ef245f12-3710-3af8-a66f-5107a19506ca.gif[/img]


3.2内存泄露

[img]http://dl2.iteye.com/upload/attachment/0106/5215/dc401b11-e291-3095-a50b-c2c2700c2690.gif[/img]

从中可以看出其中一个Thread对象占用了98.24%的空间,所以这个极可能有问题。

点击See stacktrace:
main
at java.util.Arrays.copyOf([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object; (Arrays.java:2760)
at java.util.Arrays.copyOf([Ljava/lang/Object;I)[Ljava/lang/Object; (Arrays.java:2734)
at java.util.ArrayList.ensureCapacity(I)V (ArrayList.java:167)
at java.util.ArrayList.add(Ljava/lang/Object;)Z (ArrayList.java:351)
at [color=red][b]org.frank1234.javaA.jvm.oom.HeapOOM.main([Ljava/lang/String;)V (HeapOOM.java:11)[/b][/color]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; (Native Method)

可以直接定位到源代码。

3.3引用对象

[img]http://dl2.iteye.com/upload/attachment/0106/5208/3ec03cdc-3dfc-368d-a6da-47f2fbaaac60.gif[/img]

从图中看到object[]中存放的就是list.add("i want oom, quickly");放入的字符串。

另外这个数组的深堆和浅堆都非常大。
3.4 支配树

[img]http://dl2.iteye.com/upload/attachment/0106/5210/1b41b201-16bd-3043-86d0-543d0cf073d1.gif[/img]

通过支配树可以看到占用空间比较大的对象,因为这些对象是最值得怀疑和分析的。


4 参考资料
《Java性能优化》 葛一鸣
《Java特种兵》 谢宇
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值