Java对象内存布局

文章目录

1 场景

此文主要分析:

在java中new Object()占用多少字节?在内存中的布局是怎么的?

基于版本:jdk1.8

2 内存布局图

jdk8中,Java对象的内存布局如下图:

Java对象内存布局

其中需注意:

(1)数组对象中才有数组长度这一块内存区

(2)所有的对象大小,必须是8字节整数倍。因此有个内存补齐Padding区,当Java对象的内存不够8字节的整数倍,此Padding区进行补齐。

3 代码验证

验证环境:
64位操作系统+JDK1.8

3.1 maven依赖

<dependency>
	<groupId>org.openjdk.jol</groupId>
	<artifactId>jol-core</artifactId>
	<version>0.14</version>
</dependency>

3.2 代码示例

import org.openjdk.jol.info.ClassLayout;

public class ObjectContext {
    public static void main(String[] args) {
        Object o = new Object();
        ClassLayout layout = ClassLayout.parseInstance(o);
        System.out.println(layout.toPrintable());
    }
}

3.3 输出内容

java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

3.4 分析

输出日志中显示:Instance size: 16 bytes,即new Object()占用16个字节。
其中,输出
loss due to the next object alignment

Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
表示内存补齐Padding,占用4个字节

其中:

类型 字节
对象头MarkWord 8
类型指针 4
对象内容 0
内存补齐Padding 4

3.5 补充

启动jvm参数中,禁用指针压缩,加上如下参数:

-XX:-UseCompressedOops

再次执行刚出的java代码,输出日志如下:

java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           00 1c 7f 1c (00000000 00011100 01111111 00011100) (478092288)
     12     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

虽然结果也是16个字节,但是根据:
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
内存补齐Padding,占用0个字节。
即占用分布如下:

类型 字节
对象头MarkWord 8
类型指针 8
对象内容 0
内存补齐Padding 0

4 问题解答

4.1 new空对象占用多少字节

new Object()占用多少内存字节?

当前操作系统基本都是64位,这里参照**《2 内存布局图》**,来分析64位操作系统中需要多少字节。

操作系统 对象类型 指针压缩 明细 总字节数
64位 普通对象 开启 MarkWord:8字节
类型指针:4字节
对象内容:0字节
内存补齐:4字节
16字节
64位 普通对象 关闭 MarkWord:8字节
类型指针:8字节
对象内容:0字节
内存补齐:0字节
16字节
64位 数组对象 开启 MarkWord:8字节
类型指针:4字节
数组长度:4字节
对象内容:0字节
内存补齐:0字节
16字节
64位 数组对象 关闭 MarkWord:8字节
类型指针:8字节
数组长度:4字节
对象内容:0字节
内存补齐:4字节
24字节

4.2 Java对象在内存中的布局

见**《2 内存布局图》**

上一篇:多线程一synchronized的横切面


下一篇:【故障处理】DG环境主库丢失归档情况下数据文件的恢复(4)