计算Java中Object的大小

这个问题在这里已经有了答案:

  • 在Java中,确定对象大小的最佳方法是什么? 24个答案

  • 你可以使用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 Guava在内部使用它,而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.miscUnsafe类获得了另一种解决方案。 因此,根据处理器体系结构考虑对象堆对齐并计算最大字段偏移量,可以测量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() { }
    }
    
    链接地址: http://www.djcxy.com/p/86613.html

    上一篇: Calculate size of Object in Java

    下一篇: Why is Java's boolean primitive size not defined?