众所周知,btrace中可以使用 com.sun.btrace.BTraceUtils.sizeof(Object)来计算传入的对象的大小;jmap -histo中也可以显示heap中对象大小信息,到底这两个显示的object size是“浅大小” 还是 “深大小”?
简单测试一下:
BTraceUtils.sizeof(Object):
首先来看btrace,被测试代码如下:
btrace脚本如下:
原理很简单,通过拦截TestBtrace#work(Object) 计算传入的TestBtrace对象的大小。
测试脚本如下:
执行脚本,运行结果如下:
OK,object大小才24 byte,而TestBtrace#data就是好几MB,所以证明com.sun.btrace.BTraceUtils.sizeof(Object)算出的是对象的浅大小。
如果有兴趣,可以修改TestBtrace 中的data的大小,再多试几次。
jmap -histo:
还是上面的TestBtrace.java ,稍微修改一下运行脚本,如下:
运行结果如下:
由于TestBtrace 对象是不停在创建的,所以#instances 可能会有不同,但是可以肯定的是,jmap -histo 打印的也是对象的浅大小,和btrace一样。
结论:
无论是BTraceUtils.sizeof(Object) 还是 jmap -histo,显示的都是对象的浅大小,因此,在使用jmap -histo 排查内存泄漏的问题时,除了[B等基础类型外([B等基础类型已经是其真实大小),不能单纯的通过#bytes 列判断内存占用,还是要综合考虑才行。
好,祝大家玩儿的愉快!
-- EOF --