btrace sizeOf 与 jmap -histo中对象大小说明

 

        众所周知,btrace中可以使用 com.sun.btrace.BTraceUtils.sizeof(Object)来计算传入的对象的大小;jmap -histo中也可以显示heap中对象大小信息,到底这两个显示的object size是“浅大小” 还是 “深大小”?

 

        简单测试一下:

BTraceUtils.sizeof(Object):

        首先来看btrace,被测试代码如下:

public class TestBtrace{ private static final int ten_mb = 10 * 1024 * 1024; private static final int invoke_times = 100; public static void main(String[] args) throws Exception{ int index = invoke_times; while(index -- > 0){ TestBtrace test = new TestBtrace(); work(test); Thread.sleep(1000); System.out.println(index + " remains"); } } private byte[] data = new byte[ten_mb]; public static void work(Object test){ } } 

btrace脚本如下:

import com.sun.btrace.BTraceUtils; import com.sun.btrace.annotations.BTrace; import com.sun.btrace.annotations.OnMethod; @BTrace public class TestBtraceScript { @OnMethod(clazz="TestBtrace", method="work") public static void interceptWork(Object object){ BTraceUtils.println(BTraceUtils.classOf(object)); BTraceUtils.println(BTraceUtils.sizeof(object)); BTraceUtils.println(); } }

原理很简单,通过拦截TestBtrace#work(Object) 计算传入的TestBtrace对象的大小。

测试脚本如下: 

#!/bin/sh pid=$(jps|grep TestBtrace|cut -d ' ' -f 1) if [ -n "$pid" ] then kill -9 $pid fi javac TestBtrace.java java -Xms1000m TestBtrace > /dev/null & sleep 1; pid=$(jps|grep TestBtrace|cut -d ' ' -f 1) btrace $pid TestBtraceScript.java 

执行脚本,运行结果如下: 

class TestBtrace 24 class TestBtrace 24 class TestBtrace 24 class TestBtrace 24 class TestBtrace 24 

OK,object大小才24 byte,而TestBtrace#data就是好几MB,所以证明com.sun.btrace.BTraceUtils.sizeof(Object)算出的是对象的浅大小。

如果有兴趣,可以修改TestBtrace 中的data的大小,再多试几次。

 

jmap -histo:

还是上面的TestBtrace.java ,稍微修改一下运行脚本,如下:

#!/bin/sh pid=$(jps|grep TestBtrace|cut -d ' ' -f 1) if [ -n "$pid" ] then kill -9 $pid fi javac TestBtrace.java java -Xms1000m TestBtrace > /dev/null & sleep 1; pid=$(jps|grep TestBtrace|cut -d ' ' -f 1) echo ' num #instances #bytes class name' jmap -histo $pid |grep TestBtrace 

运行结果如下: 

haitao-yao@haitaoyao-laptop:~/test$ sh test_jmap num #instances #bytes class name 128: 2 48 TestBtrace 

由于TestBtrace 对象是不停在创建的,所以#instances 可能会有不同,但是可以肯定的是,jmap -histo 打印的也是对象的浅大小,和btrace一样。

 

结论:

无论是BTraceUtils.sizeof(Object) 还是 jmap -histo,显示的都是对象的浅大小,因此,在使用jmap -histo 排查内存泄漏的问题时,除了[B等基础类型外([B等基础类型已经是其真实大小),不能单纯的通过#bytes 列判断内存占用,还是要综合考虑才行。

 

好,祝大家玩儿的愉快!

 

-- EOF --

 

 

 

你可能感兴趣的:(exception,object,测试,脚本,Class,byte)