(五)Java对象内存占用测试

纸上得来终觉浅,绝知此事要躬行

Posted by chchaooo on March 2, 2018

使用java的java.lang.instrument.Instrumentation来测试各个不同类型占用的内存空间。中间有些波折,最后使用最直接将所有类都放到同一个目录下,不使用IDE生成的目录结构,完成了相关的测试。

1. 编译Tools类

javac SizeOfObject.java

2. 编辑META-INF(文件内部内容)

Premain-Class: SizeOfObject

3. 将SizeOfObject和META-INF一起打到jar包中

jar cvfm java-agent-sizeof.jar META-INF/MANIFEST.MF  .

4. 编译测试类

javac Main.java

5. 运行测试类

java -javaagent:java-agent-sizeof.jar Main

以下是一些执行例子可以帮助理解对象的组成 简单案例

    /** 对象头(8) + 类指针(4) + padding(4) = 16 */
    static class Empty{
        
    }
    
    /** 对象头(8) + 类指针(4) + a(4) = 16 */
    static class A {
        int a;
    }
    
    /** 对象头(8) + 类指针(4) + a(4) + b(4) + padding(4) = 24 */
    static class B {
        int a;
        int b;
    }
    
    /** 对象头(8) + 类指针(4) + a(4) + b(4) + c(4) = 24 */
    static class C {
        int a;
        int b;
        int c;
    }
    
    /** 对象头(8) + 类指针(4) + a(4) + b(4) + c(4) + d(4) + padding(4) = 32 */
    static class D {
        int a;
        int b;
        int c;
        int d;
    }

上述例子执行截图

复杂案例

    static class ObjectMultiA {
        String str;     // 4
        int i1;         // 4
        byte b1;        // 1
        byte b2;        // 1
        int i2;         // 4
        Object obj;     //4
        byte b3;        // 1
    }

内存占用:对象的多个属性,虚拟机中会先按照以下顺序进行排序: 从长到短排列,引用排最后: long/double –> int/float –> short/char –> byte/boolean –> Reference。

按照以上原则,可以算出该对象的内存占用为: 8(_mark) + 4(oop指针) + 4(i1) + + 4(i2) + 1(b1) + 1(b2) + 1(b3) + 1(padding) + 4(str) + 4(obj) = 32

执行前截图:

执行后截图

代码GitHub地址: