java 对象内存布局

面试题:初始化创建的对象有多大?

答案: 16字节

Object a = new Object();  16字节
String[] b = new String[2](); 16字节 / 24字节

对象的内存布局

image
主体内容包括:

  • 对象头: MarkWord、指针、数字长度(数组对象才有)
  • 数据体: 对象的数据,初始化一般为 空
  • 数据对齐:要求对象大小,为8的倍数,而做的特殊设置

普通对象

  • 对象头:包括 :markWord + 指针
    • markword 为8个字节
    • classPointer 指针:指向对应的 class的指针,一般为 8个字节,如果开启“ -XX:+UseCompressedClassPointers”,则压缩为 4个字节。
  • 实际数据:成员变量 和 引用类型
  • 对齐 padding :(填充作用,使对象的字节永远为 8的倍数。如果对象实际为 15个字节,对齐后,会填补一个字节。)

new Object() 的大小为 16.

  • MarkWord为 8个字节,指针(Class Pointer)压缩情况下为4个字节。实体数据内容为0个,padding 操作(对齐)。最后结果为16个。
  • MarkWord为 8个字节,指针(Class Pointer)不压缩情况下为8个字节。实体数据内容为0个,padding 操作(对齐)。最后结果为16个。

数组对象

  • 对象头:markword + classPointer 指针
  • 数组长度 :数组长度 为 4个字节
  • 数组数据
  • 对齐 padding

new int[];

  • MarkWord为 8个字节,指针(Class Pointer)压缩情况下为4个字节,数组长度为 4个字节。实体数据内容为0个,padding 操作(对齐)。最后结果为16个。
  • MarkWord为 8个字节,指针(Class Pointer)不压缩情况下为8个字节,数组长度为 4个字节。实体数据内容为0个,padding 操作(对齐)。最后结果为24个。

对象头都会包什么信息

第一个 锁的信息,代表对象有没有被锁定
第二个 GC 标记,对账被GC标记的分代年龄

java 引用对象的方法有几种

2种。

  • 句柄池法(间接指针):存在一个句柄池,记录所有对象的地址。引用对象时,从句柄池中找对象地址,并引用
  • 直接指针法:通过对象头的指针,找到对象地址。

JVM 是使用直接指针法~~ !!!!

为什么要对齐为8的倍数

  假设我们使用64位操作系统,也就是说,一次寻址(读取)64个二进制位,也就是 8字节的寻址空间。换句话说,系统一次读取8个字节的内容。

常识: 一个字节为8个二进制位。

简单举例:
image
  boolean、int、char想要获取,都是读取一次就行,读取前半部分就可以。但如果想读取long需要读取两次,才能得到结果。
  所以添加了对齐操作。
image
就是这么简单,从而提升性能的。

posted @ 2024-02-05 18:40  之士咖啡  阅读(8)  评论(0编辑  收藏  举报