JVM精进之路

JVM相关问题一网打尽
帅旋
关注
充电
帅旋DevShow:专注软件开发 · Mac 数码 · 摄影分享

说说JVM对象的内存布局?

发布于 2024-08-30 | 更新于 2024-10-13

JVM对象内存布局如下图所示:

image-20240420203422302

包含以下关键部分:

  • 对象头

    • 标记字(Mark Word):这部分数据包含对象自身的运行时数据,如哈希码(HashCode)、垃圾回收信息(如年龄段、是否被锁定等)、偏向线程ID、锁状态标志等。其长度通常是一个机器字(word),在32位JVM上是4字节,在64位JVM上是8字节。对象处于不同的状态,Mark Work会有不同的取值。

      32位对象头如下图所示:

      image-20240420203441356

    • 类型指针(Klass Pointer):这是指向它的类元数据的指针,JVM通过这个指针来确定对象属于哪个类。默认8个字节,启了压缩指针的情况下,这个指针会被压缩成4个字节大小。

      启用压缩指针:-XX:+UseCompressedOops

      可以减少类型指针的大小,从而减少对象总体大小,提高内存利用率。

    • 数组长度:这是数组对象特有的部分,存储数组的长度。数组长度的存在对于数组操作非常关键,因为它需要在运行时进行边界检查以防止越界访问。

  • 实例数据:这部分是对象存储其实际信息的地方,即从类中声明的各个字段。字段的排列顺序和数据类型大小可以影响对象的总大小,因为JVM会尝试以最有效的方式来存储这些字段:

    • 字段排序:通常,为了内存对齐,JVM可能会根据字段的类型重新排序(如首先是longsdoubles,然后是ints,之后是shortschars,最后是bytesbooleans),这种排序有时候可以在不增加对象大小的情况下,最大限度地减少内部空隙。
    • 继承结构:在Java中,对象实例数据也包括从其所有父类继承的字段。
  • 对齐填充:为了使对象的总大小是8字节(在大多数现代计算机上是内存访问的最佳边界)的倍数,可能需要在对象最后添加一些填充。这种对齐可以帮助提高CPU的缓存利用率,从而提高性能。

在64位系统下,开启了压缩指针,并且压缩指针有效的情况下,对象头占用12个字节。

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/faqs/jvm/jvm-object-memory-layout.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。