JVM笔记04.HotSpot Java Object Layout

86 阅读2分钟

本文主要基于周志明老师的《深入理解Java虚拟机》。

[toc]

HotSpot Java Object Layout

本次讨论的是HotSpot虚拟机中Java实例在内存中的布局。

内存结构

普通对象

对象在内存中的存储布局可以分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

Header

Header由MarkWord和ClassPointer组成。

MarkWord在32位JVM中的长度是4字节,在64位JVM中长度是8字节。

MarkWord内存布局

*_执行过IdentityHashCode的对象上不了偏向锁。

ClassPointer是元数据类型指针,可以通过-XX:+UseCompressedClassPointers来压缩成4字节。

Instance Data

Instance Data储存着对象的属性。

  • byte 1字节、short 2字节、int 4字节、long 8字节
  • float 4字节、double 8字节
  • char 2字节
  • boolean 1字节
  • 引用类型
    • XX:+UseCompressedOops 为4字节 不开启为8字节
    • OOps:Ordinary Object Pointers
Padding

Padding将对象在内存中的大小填充至n*8字节。这也是CompressedOops的原理由来,通过将内存地址除8可以得到压缩后的地址,使用时乘8还原回来就行,通过这种方式在4字节的空间中可以表示32g的内存地址。

数组对象

  • Markword
  • ClassPointer
  • 数组长度(4字节)
  • 数组数据
    • 参考普通对象
  • Padding

Hotspot内存压缩规则(64位机)

  1. 4G以下,直接采用32位。
  2. 4G - 32G,默认开启内存压缩 ClassPointers Oops。
  3. 32G,压缩无效,使用64位。

+UseCompressedOops时自动开启+UseCompressedClassPointers。

www.cnblogs.com/yaoyuanecho…
这篇博客详细讨论了+UseCompressedOops和+UseCompressedClassPointers之间的开启关系。

Compressed Class Space

通过jstat -gc查看gc分区信息的时候,会看到一个CCSC和CCSU,这便是Compressed Class Space大小和已使用大小。Compressed Class Space中存放了Klass对象,就是类的元信息。

如果关闭UseCompressedClassPointers,那么便不会生成Compressed Class Space。

通过OpenJDK.Jol观察对象内存布局

导入依赖:

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

代码如下:

public class A {

    private int x;

    private String y;

    public static void main(String[] args) {
        ClassLayout classLayout = ClassLayout.parseClass(A.class);
        System.out.println(classLayout.toPrintable());
    }

}

输出如下:

jol.A object internals:
 OFFSET  SIZE               TYPE DESCRIPTION                               VALUE
      0    12                    (object header)                           N/A
     12     4                int A.x                                       N/A
     16     4   java.lang.String A.y                                       N/A
     20     4                    (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total