美文网首页
Java的对象内存布局

Java的对象内存布局

作者: 麦香小瑜儿 | 来源:发表于2019-03-02 21:35 被阅读0次

在 Java 虚拟机中,每个 Java 对象都有一个对象头(object header),这个由标记字段类型指针所构成。其中,标记字段用以存储 Java 虚拟机有关该对象的运行数据,如哈希码、GC 信息以及锁信息,而类型指针则指向该对象的类。

压缩指针

为了尽量较少对象的内存使用量,64 位 Java 虚拟机引入了压缩指针 [1] 的概念(对应虚拟机选项 -XX:+UseCompressedOops,默认开启),将堆中原本 64 位的 Java 对象指针压缩成 32 位的。使得对象头的大小从 16 字节降至 12 字节。当然,压缩指针不仅可以作用于对象头的类型指针,还可以作用于引用类型的字段,以及引用类型数组。

原理

默认情况下,Java 虚拟机堆中对象的起始地址需要对齐至 8 的倍数(内存对齐)。不到 8N 个字节部分,会被自动填充,称之为对象间的填充(padding)。
在默认情况下,Java 虚拟机中的 32 位压缩指针可以寻址到 2 的 35 次方个字节,也就是 32GB 的地址空间(超过 32GB 则会关闭压缩指针)。
在对压缩指针解引用时,需要将其左移 3 位,再加上一个固定偏移量,便可以得到能够寻址 32GB 地址空间的伪 64 位指针了。

字段重排序

内存对齐不仅存在于对象与对象之间,也存在于对象中的字段之间。比如说,Java 虚拟机要求 long 字段、double 字段,以及非压缩指针状态下的引用字段地址为 8 的倍数。字段重排序遵循以下两个原则:

  1. 如果一个字段占据 C 个字节,那么该字段的偏移量需要对齐至 NC。这里偏移量指的是字段地址与对象的起始地址差值。
  2. 子类所继承字段的偏移量,需要与父类对应字段的偏移量保持一致。
    字段内存对齐的其中一个原因,是让字段只出现在同一 CPU 的缓存行中。如果字段不是对齐的,那么就有可能出现跨缓存行的字段。也就是说,该字段的读取可能需要替换两个缓存行,而该字段的存储也会同时污染两个缓存行。这两种情况对程序的执行效率而言都是不利的。

对象内存相关的JVM参数

  • -XX:ObjectAlignmentInBytes,设置内存对齐字节数,默认值为 8
  • -XX:+UseCompressedOops,默认开启,将堆中原本 64 位的 Java 对象指针压缩成 32 位的。

附录

  • JVM的string内存优化

相关文章

  • java 内存布局

    Java 内存的布局主要是统计Java对象占用内存的大小。 Java对象的内存布局:对象头(Header)、实例数...

  • Java对象

    Java对象的内存布局?对象的访问?new对象的过程? 一、Java对象的内存布局 对象的创建过程就是在堆上分配实...

  • Java对象

    本文以HotSpot虚拟机为例,介绍Java对象在虚拟机中存储和使用方式。 对象的内存布局 对象在内存中存储布局可...

  • 玩转JVM中的对象及引用②:对象的内存布局及访问

    一、对象的内存布局 问:在 Java 对象创建后,到底是如何被存储在Java内存里的呢? 答:在Java虚拟机(H...

  • java对象内存布局

    前言:hotspot虚拟机中,对象存储的布局可以分为3块区域:对象头,实例数据,对齐数据 一:对象头 对象头分...

  • Java对象内存布局

    博客链接:http://www.ideabuffer.cn/2017/05/06/Java对象内存布局/ 我们知道...

  • Java对象内存布局

  • java对象内存布局

  • Java 对象内存布局

    对象在内存中的存储可以分为三个区域:对象头(Header),实例数据(Instance Data)和对齐填充(Pa...

  • Java对象内存布局

    1 场景 此文主要分析: 在java中new Object()占用多少字节?在内存中的布局是怎么的? 基于版本:j...

网友评论

      本文标题:Java的对象内存布局

      本文链接:https://www.haomeiwen.com/subject/rgoyuqtx.html