计算Java中Object的大小

计算Java中Object的大小我想记录一个对象占用多少内存(以字节为单位)(我正在比较数据结构的大小),似乎没有方法可以在Java中执行此操作。据说,C / C ++有sizeOf()方法,但这在Java中是不存在的。我尝试Runtime.getRuntime().freeMemory()在创建对象之前和之后记录JVM中的空闲内存,然后记录差异,但它只会给出0或131304,而不管结构中的元素数量是什么。请帮忙!

森林海
浏览 1811回答 3
3回答

慕田峪7331174

本java.lang.instrument.Instrumentation类提供了一个很好的方式来获得一个Java对象的大小,但它需要你定义一个premain与一个Java代理运行程序。当您不需要任何代理时,这非常无聊,然后您必须为您的应用程序提供虚拟Jar代理。所以我得到了另一种使用Unsafe该类的替代解决方案sun.misc。因此,根据处理器体系结构考虑对象堆对齐并计算最大字段偏移量,您可以测量Java对象的大小。在下面的示例中,我使用辅助类UtilUnsafe来获取sun.misc.Unsafe对象的引用。private&nbsp;static&nbsp;final&nbsp;int&nbsp;NR_BITS&nbsp;=&nbsp;Integer.valueOf(System.getProperty("sun.arch.data.model"));private&nbsp;static&nbsp;final&nbsp;int&nbsp;BYTE&nbsp;=&nbsp;8;private&nbsp;static&nbsp;final&nbsp;int&nbsp;WORD&nbsp;=&nbsp;NR_BITS/BYTE;private&nbsp;static&nbsp;final&nbsp;int&nbsp;MIN_SIZE&nbsp;=&nbsp;16;&nbsp;public&nbsp;static&nbsp;int&nbsp;sizeOf(Class&nbsp;src){ &nbsp;&nbsp;&nbsp;&nbsp;// &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Get&nbsp;the&nbsp;instance&nbsp;fields&nbsp;of&nbsp;src&nbsp;class &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;List<Field>&nbsp;instanceFields&nbsp;=&nbsp;new&nbsp;LinkedList<Field>(); &nbsp;&nbsp;&nbsp;&nbsp;do{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(src&nbsp;==&nbsp;Object.class)&nbsp;return&nbsp;MIN_SIZE; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(Field&nbsp;f&nbsp;:&nbsp;src.getDeclaredFields())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if((f.getModifiers()&nbsp;&&nbsp;Modifier.STATIC)&nbsp;==&nbsp;0){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instanceFields.add(f); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src&nbsp;=&nbsp;src.getSuperclass(); &nbsp;&nbsp;&nbsp;&nbsp;}while(instanceFields.isEmpty()); &nbsp;&nbsp;&nbsp;&nbsp;// &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Get&nbsp;the&nbsp;field&nbsp;with&nbsp;the&nbsp;maximum&nbsp;offset &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;maxOffset&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(Field&nbsp;f&nbsp;:&nbsp;instanceFields)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;offset&nbsp;=&nbsp;UtilUnsafe.UNSAFE.objectFieldOffset(f); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(offset&nbsp;>&nbsp;maxOffset)&nbsp;maxOffset&nbsp;=&nbsp;offset;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;&nbsp;(((int)maxOffset/WORD)&nbsp;+&nbsp;1)*WORD;&nbsp;}class&nbsp;UtilUnsafe&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;final&nbsp;sun.misc.Unsafe&nbsp;UNSAFE; &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;theUnsafe&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Exception&nbsp;exception&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class<?>&nbsp;uc&nbsp;=&nbsp;Class.forName("sun.misc.Unsafe"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Field&nbsp;f&nbsp;=&nbsp;uc.getDeclaredField("theUnsafe"); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f.setAccessible(true); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;theUnsafe&nbsp;=&nbsp;f.get(uc); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{&nbsp;exception&nbsp;=&nbsp;e;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UNSAFE&nbsp;=&nbsp;(sun.misc.Unsafe)&nbsp;theUnsafe; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(UNSAFE&nbsp;==&nbsp;null)&nbsp;throw&nbsp;new&nbsp;Error("Could&nbsp;not&nbsp;obtain&nbsp;access&nbsp;to&nbsp;sun.misc.Unsafe",&nbsp;exception); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;UtilUnsafe()&nbsp;{&nbsp;}}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java