Java虚拟机--Java堆中对象的创建和布局

上一篇:Java虚拟机--内存区域划分

对象的创建:

对象的创建(仅限普通对象,不包括数组和Class对象)分为五个步骤:

第一步:类加载检查

虚拟机遇到一条new指令时,首先去检查这个指令的参数是否能在常量池中定位到一个符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,就必须进行相应的类加载过程。

第二步:分配内存

类加载检查通过后,要进行分配内存。对象所需的内存大小在类加载完成后便可完全确定,为对象分配内存的任务便转化成把一块大小确定的内存从Java堆中划分出来。有两种方式:“指针碰撞”和“空闲列表”。

  • 指针碰撞:假设Java中内存是完整的,所有用过的内存放一边,没用的内存放另一边,中间放置一个指针作为分界点指示器。当需要分配内存时只需要把指针向空闲内存方向移动相应的大小即可。
  • 空闲列表:假设Java堆的内存空间不规整,已使用的内存和空闲内存交错。虚拟机维护一张表记录那些内存块是可用的。在分配的时候从表中选出一个大小合适和内存块划分给对象实例。

(使用Serial、ParNew等带Conpact过程的垃圾收集器时系统采用的分配算法是指针碰撞,使用CMS这种基于Mark-Sweep算法的垃圾收集器时,通常采用空闲列表)

除如何划分空间外,另一个问题是线程同步问题。同样有两种方案:

  • 对分配空间的动作做同步处理----虚拟机采用CAS配上失败重试的方法保证更新指针操作的原子性;
  • 把内存非配操作按照线程划分在不同的空间中进行----每个线程在Java堆中预先划分出一小块内存,称为本地线程分配缓冲(TLAB)。只有TLAB用完并分配新的TLAB时,才需要同步锁定。

第三步:初始化内存空间

内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头)。如果使用TLAB,该工作可以提前至TLAB分配时进行。

第四步:对对象进行必要设置

虚拟机要对对象进行必要设置,例如这个对象是哪个类的实例,如何找到类的元数据信息、对象的哈希码、对象的GC分代年龄等。这些信息存放在对象头中。

第五步:执行<init>方法

一般来说,执行new指令后会接着执行<init>方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象就产生了。

对象的内存布局:

对象在内存中的布局可以分为3块区域:对象头、实例数据和对齐填充。

1、对象头

对象头包括两部分信息:

  1. 第一部分用于存放对象运行时自身的数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。这部分数据的长度在32位和64位的虚拟机中分别是32bit和64bit,官方称为“Mark Word”。对象需要存储的数据很明显会超过32bit或64bit,所以Mark Word被设计为一个非固定的数据结构以便在绩效的空间内存储尽量多的数据信息,他会根据对象的状态复用自己的存储空间。
  2. 第二部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪一个类的实例。

2、实例数据

实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承的还是在子类定义的,都要记录下来。

3、对齐填充

不是必须的,也没什么特别含义,它仅仅起着占位符的作用。

下一篇:Java虚拟机--对象回收

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏锦小年的博客

python学习笔记9.1-系统交互接口

本文主要主要介绍python语言user与操作系统的交互接口,主要包括直接输入或者系统参数两种输入方式,输出主要就是print函数和format()表达式了,前...

22990
来自专栏Java学习网

Java内存模型深度解读

Java内存模型深度解读 Java内存模型规范了Java虚拟机与计算机内存是如何协同工作的。Java虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一...

26870
来自专栏哲学驱动设计

模式应用:自定义匹配

    本篇博客记录了我在工作过程中的一个设计单元。 需求 GIX4项目中需要为非国标清单进行匹配,用户自定义匹配规则。规则可以被存储到数据库中,下次重复使用...

21150
来自专栏移动开发面面观

Java学习笔记——内存管理Java内存管理

13830
来自专栏PHP在线

php日常使用总结

Private(私有): 只能在这个当前类的内部读取、修改。 Protected(受保护):能够在这个类和类的子类中读取和修改。 在方法内部通过 $this...

37980
来自专栏Java成长之路

一、JVM内存区域详解

Java中虚拟机在执行Java程序的过程中会将它所管理的内存区域划分为若干不同的数据区域。下面来介绍几个运行时数据区域。

24310
来自专栏orientlu

std::sort coredump 说起

c++ 标准库 sort() 默认采用 < 这个 operator 来排序的, 另个一个重载函数增加第三个参数,指定一个比较的函数,函数接受两个参数。 对于基...

19330
来自专栏Java职业技术分享

可能是把Java内存区域讲的最清楚的一篇文章

对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C++程序开发程序员这样为内一个 new 操作去写对应的 delete/free 操作,不...

14000
来自专栏Java帮帮-微信公众号-技术文章全总结

Java面试系列11

Java面试系列11 1 Java中的异常处理机制的简单原理和应用 当JAVA 程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。...

37280
来自专栏搜云库

《深入理解Java虚拟机》(二)java虚拟机运行时数据区

Java虚拟机运行时数据区 详解 2.1 概述 本文参考的是周志明的 《深入理解Java虚拟机》,为了整理思路,简单记录一下,方便后期查阅。 2.2 运行时数据...

32360

扫码关注云+社区

领取腾讯云代金券