专栏首页云霄雨霁JVM--对象创建

JVM--对象创建

*将以前写的一篇博客重新整理

1  对象的创建

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

第一步:类加载检查

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

JVM--类加载

第二步:分配内存

类加载检查通过后,要进行分配内存。对象所需的内存大小在类加载完成后便可完全确定,为对象分配内存的任务便转化成把一块大小确定的内存从Java堆中划分出来。

有两种方式:“指针碰撞”和“空闲列表”:

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

这两种分配方式并没有绝对的好坏之分,有的虚拟机使用指针碰撞,有的虚拟机使用空闲列表。

除如何划分空间外,另一个问题是线程同步问题。因为即使移动一个指针,在并发情况下也可能是不安全的。解决这个问题同样有两种方案:

  • 对分配空间的动作做同步处理
  • 把内存分配操作按照线程划分在不同的空间中进行--每个线程在Java堆中预先划分出一小块内存,称为本地线程分配缓冲(TLAB)。哪个线程需要分配内存,就在哪个线程的TLAB上分配。只有TLAB用完并分配新的TLAB时,才需要同步锁定

第三步:初始化内存空间

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

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

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

第五步:执行<init>方法

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

2  对象的内存布局

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

2.1  对象头

对象头包括两部分信息:

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

2.2  实例数据

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

2.3  对齐填充

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

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

我来说两句

0 条评论
登录 后参与评论

相关文章

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

    SuperHeroes
  • Java虚拟机--对象回收

    SuperHeroes
  • 分布式Java--基于远程调用实现系统间通信

    远程调用方式就是尽可能将系统间的调用模拟为系统内的调用,让使用者感觉远程调用就像是调用本地接口一样。但远程调用并不能做到完全透明,因为存在网络问题、超时问题、序...

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

    SuperHeroes
  • JVM-解密Java对象

    在Java程序运行过程中时时刻刻都有对象被创建出来,对象的创建方式有很多种,最常见的就是new,其次还有clone和反序列化。下面我们一起来解密对象的创建、内存...

    shysh95
  • Java 自动内存管理机制及性能优化

    首先来看看Java虚拟机所管理的内存包括哪些区域,就像我们要了解一个房子,我们得先知道这个房子大体构造。根据《Java虚拟机规范(Java SE 7 版)》的规...

    我就是马云飞
  • Java中堆的内存泄漏和内存溢出 及问题解决 参数设置

    1、内存泄漏:严格来说,只有对象不会再被程序用到了,但是GC又不能回收他们的情况,才叫内存泄漏,由于这些对象不能被垃圾收集掉,这样的对象多了,有可能就会OOM。

    一个长不胖的程序Yuan
  • 面试官:小伙子,你给我说一下Java中什么情况会导致内存泄漏呢?

    内存泄露:指程序中动态分配内存给一些临时对象,但对象不会被GC回收,它始终占用内存,被分配的对象可达但已无用。即无用对象持续占有内存或无用对象的内存得不到及时释...

    用户2781897
  • JVM内存分配策略,及垃圾回收算法

    说起垃圾收集(Garbage Collection, GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当...

    李红
  • 高频面试点:Android性能优化之内存优化(上篇)

    链接:https://juejin.im/post/5e72b2d151882549236f9cb8

    陈宇明

扫码关注云+社区

领取腾讯云代金券