Java对象大小计算

我们知道Java中分基本类型和对象。基本类型比如byte一个字节,int 4个字节,对象指针4个字节(32位主机)或者8个字节(64位主机位开启压缩指针)。但是我们new 一个对象时实际占用内存空间大小如何计算呢?

java agent Instrument机制中Instrumentation对象有一个getObjectSize方法可以获取对象的大小。

1
/**     * Returns an implementation-specific approximation of the amount of storage consumed by     * the specified object. The result may include some or all of the object's overhead,     * and thus is useful for comparison within an implementation but not between implementations.     *     * The estimate may change during a single invocation of the JVM.     *     * @param objectToSize     the object to size     * @return an implementation-specific approximation of the amount of storage consumed by the specified object     * @throws java.lang.NullPointerException if the supplied Object is <code>null</code>.     */    long    getObjectSize(Object objectToSize);
1
/**
1
* Returns an implementation-specific approximation of the amount of storage consumed by
1
* the specified object. The result may include some or all of the object's overhead,
1
* and thus is useful for comparison within an implementation but not between implementations.
1
*
1
* The estimate may change during a single invocation of the JVM.
1
*
1
* @param objectToSize     the object to size
1
* @return an implementation-specific approximation of the amount of storage consumed by the specified object
1
* @throws java.lang.NullPointerException if the supplied Object is <code>null</code>.
1
*/
1
long
1
getObjectSize(Object objectToSize);

注意这个方法计算对象大小时只计算对象属性指针大小,不包括指针指向实际对象大小。

基本上64位主机上new一个没有任何属性的对象大概占用16个字节

  • 启用UseCompressedOops时8(markword) + 4 (类指针) + 4 (padding)= 16 个字节
  • 不启用UseCompressedOops时8(markword) + 8 (类指针) = 16 个字节

启用UseCompressedOops时8(markword) + 4 (类指针) + 4 (padding)= 16 个字节

不启用UseCompressedOops时8(markword) + 8 (类指针) = 16 个字节

更多对象大小可以参考

1
/**     * -XX:+UseCompressedOops: mark/8 + Klass/8  = 16     * -XX:-UseCompressedOops: mark/8 + Klass/4  + padding/4 = 16     */    static class X1 {    }    /**     * -XX:+UseCompressedOops: mark/8 + Klass/4  + a/4 = 16     * -XX:-UseCompressedOops: mark/8 + Klass/8 + a/4 + padding/4 = 24     */    static class X2 {        int a = 0;    }    /**     * -XX:+UseCompressedOops: mark/8 + Klass/4  + i/4 = 16     * -XX:-UseCompressedOops: mark/8 + Klass/8 + i/8 = 24     */    static class X3 {        Integer i = new Integer(0);    }    /**     * -XX:+UseCompressedOops: mark/8 + Klass/4  + size/4  = 16     * -XX:-UseCompressedOops: mark/8 + Klass/8 + size/4 + padding/4 = 24     */    static class X4 {        int[] a = new int[100];    }    /**     * -XX:+UseCompressedOops: mark/8 + Klass/4  + size/4  = 16     * -XX:-UseCompressedOops: mark/8 + Klass/8 + size/4 + padding/4 = 24     */    static class X5 {        Integer[] a = new Integer[100];    }    /**     * -XX:+UseCompressedOops: mark/8 + Klass/4  + i/4 + l/8 + d/8  = 32     * -XX:-UseCompressedOops: mark/8 + Klass/8 + i/4 + l/8 + d/8 + padding/4= 40     */    static class X6 {        int i = 0;        long l = 0;        double d = 0;    }    /**     * -XX:+UseCompressedOops: mark/8 + Klass/4  + size/4 = 16     * -XX:-UseCompressedOops: mark/8 + Klass/8 + size/4 + padding/4= 24     */    static class X7 {        int[] a = {1, 2, 3};    }
1
/**
1
* -XX:+UseCompressedOops: mark/8 + Klass/8  = 16
1
* -XX:-UseCompressedOops: mark/8 + Klass/4  + padding/4 = 16
1
*/
1
static class X1 {
1
}
1
/**
1
* -XX:+UseCompressedOops: mark/8 + Klass/4  + a/4 = 16
1
* -XX:-UseCompressedOops: mark/8 + Klass/8 + a/4 + padding/4 = 24
1
*/
1
static class X2 {
1
int a = 0;
1
}
1
/**
1
* -XX:+UseCompressedOops: mark/8 + Klass/4  + i/4 = 16
1
* -XX:-UseCompressedOops: mark/8 + Klass/8 + i/8 = 24
1
*/
1
static class X3 {
1
Integer i = new Integer(0);
1
}
1
/**
1
* -XX:+UseCompressedOops: mark/8 + Klass/4  + size/4  = 16
1
* -XX:-UseCompressedOops: mark/8 + Klass/8 + size/4 + padding/4 = 24
1
*/
1
static class X4 {
1
int[] a = new int[100];
1
}
1
/**
1
* -XX:+UseCompressedOops: mark/8 + Klass/4  + size/4  = 16
1
* -XX:-UseCompressedOops: mark/8 + Klass/8 + size/4 + padding/4 = 24
1
*/
1
static class X5 {
1
Integer[] a = new Integer[100];
1
}
1
/**
1
* -XX:+UseCompressedOops: mark/8 + Klass/4  + i/4 + l/8 + d/8  = 32
1
* -XX:-UseCompressedOops: mark/8 + Klass/8 + i/4 + l/8 + d/8 + padding/4= 40
1
*/
1
static class X6 {
1
int i = 0;
1
long l = 0;
1
double d = 0;
1
}
1
/**
1
* -XX:+UseCompressedOops: mark/8 + Klass/4  + size/4 = 16
1
* -XX:-UseCompressedOops: mark/8 + Klass/8 + size/4 + padding/4= 24
1
*/
1
static class X7 {
1
int[] a = {1, 2, 3};
1
}

更多参考github项目:https://github.com/shidongwa/java-agent