Java Object 组成
先看一下一个Object对象的组成部分及大小
| 32位 | 64位压缩指针 | 64位 | |
|---|---|---|---|
| 对象头(Header) | 8b | 12b | 16b |
| 实例数据(Data) | - | - | - |
| 对象填充(Padding) | 4b倍 | 8b倍 | 8b倍 |
数组需要额外的内存存储数组的长度,在32位上占用4个字节,在64位上占用8个字节,这也是为什么数组的长度小于2的32次方。
据此可以推断出基本类型大小如下所示
| 类型 | 对象头 | 数据 | 填充前 | 填充 | 总大小 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 类型 | 32 | 64- | 64 | 32 | 64 | 32 | 64- | 64 | 32 | 64- | 64 | 32 | 64- | 64 |
| Byte | 8 | 12 | 16 | 1 | 1 | 9 | 13 | 17 | 3 | 3 | 7 | 12 | 16 | 24 |
| Short | 8 | 12 | 16 | 2 | 2 | 10 | 14 | 18 | 2 | 2 | 6 | 12 | 16 | 24 |
| Integer | 8 | 12 | 16 | 4 | 4 | 12 | 16 | 20 | - | - | 4 | 12 | 16 | 24 |
| Long | 8 | 12 | 16 | 8 | 8 | 16 | 20 | 24 | - | 4 | - | 16 | 24 | 24 |
| Float | 8 | 12 | 16 | 4 | 4 | 12 | 16 | 20 | - | - | 4 | 12 | 16 | 24 |
| Double | 8 | 12 | 16 | 8 | 8 | 16 | 20 | 24 | - | 4 | - | 16 | 24 | 24 |
| Char | 8 | 12 | 16 | 2 | 2 | 10 | 14 | 18 | 2 | 2 | 6 | 12 | 16 | 24 |
| Boolean | 8 | 12 | 16 | 4 | 4 | 12 | 16 | 20 | - | - | 4 | 12 | 16 | 24 |
| 数组 | 12 | 16 | 24 | - | - | - | - | - | - | - | - | - | - | - |
从这里也可以看出为什么Boolean用4b而不是1b,开启指针压缩后可以节省大概30%的内存。
对象头详解
对象头内分为运行时元数据(Mark Word)、类型指针(Klass Point)。
元数据在32位上占用4b,在64位上占用8b;指针在32位上占4b,在64位上占8b,开启指针压缩后为4b;
32位对象头内部信息
64位对象头内部信息