四、Java对象的内存布局

上篇博客介绍的对象的创建过程,本文来介绍一下对象的组成结构。 在HotSpot虚拟机中,对象在内存中的布局划分为3个区域:对象头(Header),实例数据(Instance Data)以及对齐填充(Padding)。

对象头

HotSpot虚拟机对象的对象头一般包含两部分信息。

  1. 第一部分用于存储对象自身的运行时数据,例如HashCodeGC分代年龄等信息。在32位和64位的JVM中,这部分数据分别为32bit64bit,官方称这部分数据为Mark Word
  2. 另一部分用于存储对象的类型指针,该指针指向它的类元数据的指针,JVM通过这个指针来确定对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身,在后面的博文中将进行讨论。

另外,如果对象是一个Java数组,那么对象头中还必须有一块用于记录数据长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是从数据的元数据中却无法确定数据的大小。 之前提到对象头一般包含两部分信息,这是因为如果对象是一个数组,那么对象头还需要有额外的空间用于存储数组的长度,并且这部分数据也随着JVM位数的不同而不同:32位的JVM上,该区域的长度为32bit,在64位未开启压缩指针的JVM中,这部分数据的长度为64bit,否则为32bit

实例数据

实例数据部分是对象真正存储有效信息的区域,存储了代码中定义的各种字段的内容,包括从父类继承下来的字段和子类中定义的字段。 实例数据紧随对象头,为了提高存储空间的利用率,这部分数据的存储顺序会受到虚拟机分配策略参数(FieldsAllocationStyle)和字段在Java源码中定义顺序的影响。

HotSpot虚拟机默认的分配策略如下所示:

  • doubles & longs
  • ints & floats
  • shorts & chars
  • booleans & bytes
  • references

可以看出,相同宽度的字段总是被分配到一起,并且在满足这个条件的前提下,在父类中定义的字段会出现在子类字段之前。

对齐填充

对齐填充这部分不是必须存在的,这部分仅仅是起着占位符的作用。由于HotSpot虚拟机的自动内存管理系统要求对象的起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。而对象头部分正好是8字节的倍数(1倍或两倍)。因此当对象实例部分数据没有对齐时,就需要对剩余的部分进行填充。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏mukekeheart的iOS之旅

《JavaScript高级程序设计》学习笔记(3)——变量、作用域和内存问题

欢迎关注本人的微信公众号“前端小填填”,专注前端技术的基础和项目开发的学习。 本节内容对应《JavaScript高级程序设计》的第四章内容。 1、函数:通过函数...

29660
来自专栏C/C++基础

C++输入输出操作符重载

C++中输入操作符是>>,输出操作符是<<,又叫做流对象的“插入操作符”和“提取操作符“。其实这两个操作符最初是在C语言中用于整数的移位运算,到了C++中才利用...

9320
来自专栏GreenLeaves

C# 命名空间和程序集

一、命名空间 1、通过使用using关键字引入命名空间,减少代码量 命名空间对相关的类型进行逻辑分组,通过命名空间能快速的定位到相关的类型,例如:在System...

23580
来自专栏决胜机器学习

正则表达式学习笔记

正则表达式学习笔记 (原创内容,转载请注明来源,谢谢) 首先,学习正则表达式,很推荐一篇博客,http://www.cnblogs.com/deerchao...

366120
来自专栏白驹过隙

Python - 学习经验分享

331120
来自专栏Python

python中__get__,__getattr__,__getattribute__的区别

__get__,__getattr__和__getattribute都是访问属性的方法,但不太相同。  object.__getattr__(self, nam...

17200
来自专栏黑泽君的专栏

打印println()方法的逻辑

9520
来自专栏大闲人柴毛毛

深入Java虚拟机——JVM内存详解

在C++中,程序员拥有每一个对象的所有权,但与此同时还肩负着释放对象内存空间的责任;而Java由于有了虚拟机的帮助,程序员拥有对象的所有权的同时不再需要释放对象...

369130
来自专栏云霄雨霁

Java--类和对象之基础知识

16430
来自专栏Python小屋

Python运算符+与+=的那些事

这两个运算符很多语言都提供了,好像也没啥好说的,不就是像下面这样子用嘛。 >>> x = 3 >>> y = x+6 >>> y 9 >>> x += 6 >>...

28150

扫码关注云+社区

领取腾讯云代金券