[Home]   [TOC]

Study_Java_HotSpot_ObjectLayout  
Java Object Layout
Updated Nov 4, 2012 by jht5...@gmail.com

Java对象的内存结构 [1]

规则1:所有的对象都按8字节对齐

规则2:类属性按如下规则排序:

1. doubles and longs
2. ints and floats
3. shorts and chars
4. booleans and bytes
5. references
对象属性按各自间隙对齐,即按4字节对齐,通常情况下如果按4字节对象,那么读入4个字节到寄存器时性能要高的多

规则3:属于不同类的类属性不会混合在一起,顺序是先父类(按规则2排序),接下来是子类

规则4:父类的最后一个属性和子类的第一个属性按4字节对齐

规则5:如果子类的第一个属性是long或double,和父类无法按8字节对齐,那么JVM会按int,short,byte和reference的顺序将一个属性放到子类前直到空隙被填满



示例1:

class MyClass {
    byte a;
    int c;
    boolean d;
    long e;
    Object f;        
}

>>>>

[HEADER:  8 bytes]  8
[e:       8 bytes] 16
[c:       4 bytes] 20
[a:       1 byte ] 21
[d:       1 byte ] 22
[padding: 2 bytes] 24
[f:       4 bytes] 28
[padding: 4 bytes] 32

示例2:

class A {
   long a;
   int b;
   int c;
}

class B extends A {
   long d;
}

>>>>

[HEADER:  8 bytes]  8
[a:       8 bytes] 16
[b:       4 bytes] 20
[c:       4 bytes] 24
[d:       8 bytes] 32

示例3:

class A {
   byte a;
}

class B {
   byte b;
}

>>>>

[HEADER:  8 bytes]  8
[a:       1 byte ]  9
[padding: 3 bytes] 12
[b:       1 byte ] 13
[padding: 3 bytes] 16

示例4:

class A {
  byte a;
}

class B {
  long b;
  short c;  
  byte d;
}

>>>>

[HEADER:  8 bytes]  8
[a:       1 byte ]  9
[padding: 3 bytes] 12
[c:       2 bytes] 14
[d:       1 byte ] 15
[padding: 1 byte ] 16
[b:       8 bytes] 24

示例5:

new boolean[3]

>>>>

[HEADER:  12 bytes] 12
[[0]:      1 byte ] 13
[[1]:      1 byte ] 14
[[2]:      1 byte ] 15
[padding:  1 byte ] 16

示例6:

new long[3]

>>>>

[HEADER:  12 bytes] 12
[padding:  4 bytes] 16
[[0]:      8 bytes] 24
[[1]:      8 bytes] 32
[[2]:      8 bytes] 40



MemoryLayoutSpecification [2]:

  /**
   * Describes constant memory overheads for various constructs in a JVM implementation.
   */
  public interface MemoryLayoutSpecification {

    /**
     * Returns the fixed overhead of an array of any type or length in this JVM.
     *
     * @return the fixed overhead of an array.
     */
    int getArrayHeaderSize();

    /**
     * Returns the fixed overhead of for any {@link Object} subclass in this JVM.
     *
     * @return the fixed overhead of any object.
     */
    int getObjectHeaderSize();

    /**
     * Returns the quantum field size for a field owned by an object in this JVM.
     *
     * @return the quantum field size for an object.
     */
    int getObjectPadding();

    /**
     * Returns the fixed size of an object reference in this JVM.
     *
     * @return the size of all object references.
     */
    int getReferenceSize();

    /**
     * Returns the quantum field size for a field owned by one of an object's ancestor superclasses
     * in this JVM.
     *
     * @return the quantum field size for a superclass field.
     */
    int getSuperclassFieldPadding();
  }

32位:

new MemoryLayoutSpecification() {
    @Override public int getArrayHeaderSize() {
        return 12;
    }
    @Override public int getObjectHeaderSize() {
        return 8;
    }
    @Override public int getObjectPadding() {
        return 8;
    }
    @Override public int getReferenceSize() {
        return 4;
    }
    @Override public int getSuperclassFieldPadding() {
        return 4;
    }
}

64位压缩指针:

new MemoryLayoutSpecification() {
    @Override public int getArrayHeaderSize() {
        return 16;
    }
    @Override public int getObjectHeaderSize() {
        return 12;
    }
    @Override public int getObjectPadding() {
        return 8;
    }
    @Override public int getReferenceSize() {
        return 4;
    }
    @Override public int getSuperclassFieldPadding() {
        return 4;
    }
}

64位:

new MemoryLayoutSpecification() {
    @Override public int getArrayHeaderSize() {
        return 24;
    }
    @Override public int getObjectHeaderSize() {
        return 16;
    }
    @Override public int getObjectPadding() {
        return 8;
    }
    @Override public int getReferenceSize() {
        return 8;
    }
    @Override public int getSuperclassFieldPadding() {
        return 8;
    }
}


参数资料

[1]. http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html
[2]. https://github.com/twitter/commons/blob/master/src/java/com/twitter/common/objectsize/ObjectSizeCalculator.java