介绍两种获取JAVA对象内存大小的方法。
第一种:Instrumentation
简介:
使用java.lang.instrument 的Instrumentation来获取一个对象的内存大小。利用Instrumentation并且通过代理我们可以监测在JVM运行的程序的功能,它的原理是修改方法的字节码。
packagecom.dingtongblog.size; importjava.lang.instrument.Instrumentation; public classObjectSize { private static volatileInstrumentation instru; public static voidpremain(String args, Instrumentation inst) { instru =inst; } public staticLong getSizeOf(Object object) { if (instru == null) { throw new IllegalStateException("Instrumentation is null"); } returninstru.getObjectSize(object); } }
java -cmf manifest.txt simpleSize.jar com/dingtongblog/size/ObjectSize.class
运行
-javaagent:jarpath[=options]
java -javaagent:simpleSize.jar TestMain
(当前TestMain和simpleSize.jar在同一目录下)
测试代码如下:
importcom.dingtongblog.size.ObjectSize; public classTestMain { public static voidmain(String[] args) { String a = newString(aa); System.out.println(ObjectSize.getSizeOf(a)); } }
-javaagent:D:\sizeofag.jar
测试代码:
public classTestMain { public static void main(String[] args) throwsIllegalAccessException { String a = newString(aa); System.out.println(SizeOfAgent.fullSizeOf(a)); System.out.println(SizeOfAgent.sizeOf(a)); }
可以看到输出的结果40,24
jmap -histo <pid> (pid为当前JAVA进程的id)
jmap -histo 20230
jmap -dump:format=b,file=<filename>
可以把java的堆以hprof 二进制格式输出到一个文件中,然后通过jhat命令来查看,jhat会生成一个页面,能比较直观的查看堆详情。但是jhat需要的内存空间为dump文件的几倍,如果dump文件比较大会遇到OOM错误,这时候可以通过MAT来浏览堆信息。
jmap -dump:format=b,file=d:\dump.txt
jhat filename ;
(filename为之前dump出来的文件) 会解析JAVA 堆的DUMP文件并且会启动一个web服务器,服务器的默认端口为7000,命令执行完之后就可以通过127.0.0.1:7000访问堆详情了。
jhat d:\dump.txt