内容简介
对象头
实例数据
原生类型(primitive type)的内存占用如下:
对齐填充
对象内存占用(前提回顾)
首先根据以上的计算规则,进行一个简单的验证。使用下面的程序进行验证:
public class Test {
public static void main(String[] args) throws InterruptedException {
TestObject testObject = new TestObject();
Thread.sleep(600 * 1000);
System.out.println(testObject);
}
}
class TestObject {
private int i;
private double d;
private char[] c;
public TestObject() {
this.i = 1;
this.d = 1.0;
this.c = new char[]{'a', 'b', 'c'};
}
}
TestObject对象有四个属性,分别为int, double, Byte, char[]类型。在打开指针压缩(-XX:+UseCompressedOops)的情况下,在64位机器上,TestObject占用的内存大小应为:
当指针压缩关闭时(-XX:-UseCompressedOops),在64位机器上,TestObject占用的内存大小应为:
包装类型
包装类型的对象内存占用情况如下:
数组
-
基础数据类型数组占用的空间包括数组对象头以及基础数据类型数据占用的内存空间。
-
对象数组中存放的是对象的引用,所以对象数组本身的大小=数组对象头+length * 引用指针大小,总大小为对象数组本身大小+存放的数据的大小之和。
举两个例子:
int[10]:
new Integer[3]:
关闭压缩:
Integer数组本身:24(header) + 3 * 8(Integer reference) = 48 bytes;
开启压缩:
String
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
}
因此,在关闭指针压缩时,一个String本身需要 16(Header) + 8(char[] reference) + 4(int) = 32 bytes。
56 + length * 2 bytes(char的18bit) (8字节对齐)。
举几个例子。
String本身:12(Header) + 4(char[] reference) + 4(int hash) = 20(padding) -> 24 (bytes);