计算在Java中的对象的大小

我想logging一个对象占用了多less内存(希望是字节)(我正在比较数据结构的大小),似乎没有办法在Java中这样做。 据推测,C / C ++有sizeOf()方法,但这在Java中是不存在的。 我尝试在创build对象之前和之后用Runtime.getRuntime().freeMemory()loggingJVM中的空闲内存,然后logging差异,但它只会给0或131304,而不pipe它们之间的数目是多less元素在结构中。 请帮助!

你可以使用java.lang.instrumentation包:

http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/Instrumentation.html

它有一个方法可以用来获得对象大小的实现特定的近似值,以及与对象相关的开销。

Sergey联系的答案是一个很好的例子,我将在这里重新发布,但是你应该从他的评论中看到:

 import java.lang.instrument.Instrumentation; public class ObjectSizeFetcher { private static Instrumentation instrumentation; public static void premain(String args, Instrumentation inst) { instrumentation = inst; } public static long getObjectSize(Object o) { return instrumentation.getObjectSize(o); } } 

使用getObjectSize:

 public class C { private int x; private int y; public static void main(String [] args) { System.out.println(ObjectSizeFetcher.getObjectSize(new C())); } } 

来源例如:

在Java中,确定对象大小的最佳方法是什么?

看看https://github.com/DimitrisAndreou/memory-measurer番石榴在内部使用它,ObjectGraphMeasurer是特别直接使用开箱即用,没有任何特殊的命令行参数。;

 import objectexplorer.ObjectGraphMeasurer; public class Measurer { public static void main(String[] args) { Set<Integer> hashset = new HashSet<Integer>(); Random random = new Random(); int n = 10000; for (int i = 1; i <= n; i++) { hashset.add(random.nextInt()); } System.out.println(ObjectGraphMeasurer.measure(hashset)); } } 

java.lang.instrument.Instrumentation类提供了一个获取Java对象大小的好方法,但它需要你定义一个premain并用java代理运行你的程序。 当你不需要任何代理时,这是非常无聊的,然后你必须提供一个虚拟Jar代理到你的应用程序。

所以我从sun.misc得到了一个使用Unsafe类的替代解决scheme。 因此,根据处理器体系结构考虑堆alignment问题并计算最大字段偏移量,可以测量Java对象的大小。 在下面的示例中,我使用辅助类UtilUnsafe来获取对sun.misc.Unsafe对象的引用。

 private static final int NR_BITS = Integer.valueOf(System.getProperty("sun.arch.data.model")); private static final int BYTE = 8; private static final int WORD = NR_BITS/BYTE; private static final int MIN_SIZE = 16; public static int sizeOf(Class src){ // // Get the instance fields of src class // List<Field> instanceFields = new LinkedList<Field>(); do{ if(src == Object.class) return MIN_SIZE; for (Field f : src.getDeclaredFields()) { if((f.getModifiers() & Modifier.STATIC) == 0){ instanceFields.add(f); } } src = src.getSuperclass(); }while(instanceFields.isEmpty()); // // Get the field with the maximum offset // long maxOffset = 0; for (Field f : instanceFields) { long offset = UtilUnsafe.UNSAFE.objectFieldOffset(f); if(offset > maxOffset) maxOffset = offset; } return (((int)maxOffset/WORD) + 1)*WORD; } class UtilUnsafe { public static final sun.misc.Unsafe UNSAFE; static { Object theUnsafe = null; Exception exception = null; try { Class<?> uc = Class.forName("sun.misc.Unsafe"); Field f = uc.getDeclaredField("theUnsafe"); f.setAccessible(true); theUnsafe = f.get(uc); } catch (Exception e) { exception = e; } UNSAFE = (sun.misc.Unsafe) theUnsafe; if (UNSAFE == null) throw new Error("Could not obtain access to sun.misc.Unsafe", exception); } private UtilUnsafe() { } } 

“Java sizeof”的谷歌search导致了一个关于javaworld上的Java sizeof的好文章。 其实,一个有趣的阅读。

为了回答你的问题,没有一个与“sizeof()”相当的Java语言,但是这篇文章描述了几种获得实例化类的字节大小的方法。