100 分求助 ! 在JAVA 中如何获取一个对象占用的实际内存大小?

解决方案 »

  1.   

    long beforeMemory=Runtime.getRuntime().totalMemory();
    MyObject obj=new MyOjbect();
    long afterMemory=Runtime.getRuntime().totalMemory();
            System.out.println("Memory used:"+(beforeMemory-afterMemory));
      

  2.   

    空对象占8个字节
    有数据成员的话,你按byte/boolean=1,char/short=2,int/float=4,long/double=8,对象引用=4累加,然后对齐到8个字节的倍数。
    比如
    class A{
        int a;
        char b;
    }
    占 8(基本)+8(int 4+char 2=6,对齐到8)= 16个字节
    再比如:
    class B{
        Integer a;
        long b;
        byte c;
    }
    占 8(基本)+16(对象引用4+long8+byte1=13,对齐到16)= 32个字节===============
    如果你是从别的类继承的,父类的也要算上。
      

  3.   

    terry_yip(搞了几年开发,现在才来恶补基础,请别见笑!)  
    你的还要减去那个LONG数据的空间,还有OBJ的Reference
      

  4.   

    纠正一下刚才说的:空对象占8个字节
    有数据成员的话,你把数据成员按基本数据类型和对象引用分开统计。
    基本数据类型按byte/boolean=1,char/short=2,int/float=4,long/double=8,累加,然后对齐到8的倍数。
    对象引用按每个4字节,累加,然后对齐到8个字节的倍数。
    =============
    对象占用字节数=基本的8字节+基本数据类型所占的+对象引用所占的比如
    class A{
        int a;
        char b;
    }
    占 8(基本)+8(int 4+char 2=6,对齐到8)= 16个字节
    再比如:
    class B{
        Integer a;
        long b;
        byte c;
    }
    占 8(基本)+8(long4+byte1=5,对齐到8)+8(对象引用4,对齐到8)=32个字节===============
    如果你是从别的类继承的,父类的也要算上。
      

  5.   

    另外需要说明的是:这跟JVM的实现有一定的关系,我上面说的是sun java 1.5.07的JVM。
      

  6.   

    还是说错了,郁闷~~~,再改:再比如:
    class B{
        Integer a;
        long b;
        byte c;
    }
    占 8(基本)+16(long8+byte1=9,对齐到16)+8(对象引用4,对齐到8)=32个字节
      

  7.   

    我倒,用gc不行吧。这样可以得到一个对象序列化以后的大小:
    ByteArrayOutputStream bs = new ByteArrayOutputStream();
    ObjectOutputStream os = new ObjectOutputStream(bs);
    A a = new A();
    os.writeObject(a);
    os.flush();
    System.out.println(bs.size());
      

  8.   

    用 Runtime.getRuntime().totalMemory() 是不行的,太不准了!一个对象才多大呀?这么算?
    对象序列化也不精确吧?如果有trasiant的属性怎么办?
    还是像(hbwhwang(catmiw的ID已经停用,现在用这个) )这样算吧!
      

  9.   

    System.out.println(Runtime.getRuntime().totalMemory() / 1024 + " - "  + 
    Runtime.getRuntime().freeMemory() /1024 );
      

  10.   

    hbwhwang(catmiw的ID已经停用,现在用这个)  简洁 ,实用
      

  11.   

    空对象占8个字节
    有数据成员的话,你按byte/boolean=1,char/short=2,int/float=4,long/double=8,对象引用=4累加,然后对齐到8个字节的倍数。
    比如
    class A{
        int a;
        char b;
    }
    占 8(基本)+8(int 4+char 2=6,对齐到8)= 16个字节
    再比如:
    class B{
        Integer a;
        long b;
        byte c;
    }
    占 8(基本)+16(对象引用4+long8+byte1=13,对齐到16)= 32个字节
      

  12.   

    hbwhwang(catmiw的ID已经停用,现在用这个)说的不错.
      

  13.   

    不止是要算上long的大小,而且,例如你初始化一个Connection对象,肯定有其它的很多个别的对象会连锁地初始化的,而这些副带产生的对象,程序员是无从得知的。所以只能大约地估算一下对象的大小,其实我在实际应用中,得到对对象的大小都是用于估算性能的,如果一个对象大到有十几M的,我们就要注意优化一下算法,或者初始化后,要设为null,好让GC更快地发现这个对象没有引用而释放它。我的方法的确不是精准到字节的,盼有高手过给出一个精准到字节的算法,如果说要算上父类的大小,那么每个类你都不确定有多少个父类,怎么能写出一个通用的方法出来算对象的大小呢?难道每次都查一下DOC,然后自己人脑判断加上去?
      

  14.   

    呵呵,看来下一版JAVA应该推出 sizeof
      

  15.   

    healer_kx(甘草(朝圣中... ...)):
    是应该推出这个方法,实用着呢!
      

  16.   

    long beforeMemory=Runtime.getRuntime().totalMemory();
    MyObject obj=new MyOjbect();
    long afterMemory=Runtime.getRuntime().totalMemory();
            System.out.println("Memory used:"+(beforeMemory-afterMemory));
      

  17.   

    hehe,hbwhwang 兄言之凿凿,佩服!看样子得研读过 Sun JDK 的源码才说得出来。不过要是我,即使去看了源码也未必能看清楚。空对象占的 8 个字节是怎么回事儿呢?我想,作为一个“对象”,至少应该保留一个引用,指向它的 class,这应该占 4 个字节。那么,另外 4 个字节是什么呢?难道仅仅是“对齐到 8”~~
      

  18.   

    hbwhwang(catmiw的ID已经停用,现在用这),强人!
    在武汉?
      

  19.   

    我要统计出在一个运行过程中,单个jar包中总共创建和消耗对象的大小