概述:

  上一篇文章,介绍了虚拟机类加载的过程,那么类加载好之后,虚拟机下一步该干什么呢。我们知道java是面向对象的编程语言,所以对象可以说是java'的灵魂,这篇文章我们就来介绍

虚拟机是如何创建对象、对象内存分配以及对象是如何使用的(访问定位)。由于各个虚拟机的实现不尽相同,所以这里我们以最常用的HotSpot虚拟机为例来介绍。

对象的创建:

  对象在虚拟机中创建的步骤如下:

  1. 当虚拟机遇到一条字节码new指令时,首先会去检查这个类是否被加载、解析和初始化,如果没有,则执行类加载(类加载步骤这里就不介绍了,请查看JVM(三))。
  2. 类加载检查通过后,接下来虚拟机将在堆中为新生对象分配和对象同等大小的内存。
  3. 内存分配完之后,虚拟机会将分配到的内存空间(不包括对象头)都初始化为零值,保证了对象的实例字段有初始值,使得不赋值也可以使用,只是值为零而已(注意,如果是引用对象则为null)。
  4. 接下来,java虚拟机还要对对象进行必要的设置,比如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。
  5. 执行Class文件中<init>()方法,即构造函数,这样一个真正可用的对象才算完全构建完成。

对象的内存布局:

  在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头、实例数据和对其填充。

对象头:

  HotSpot虚拟机对象的对象头部分包括两类信息:

  1. 第一类是用于存储对象自身的运行数据,如何哈希码(hashcode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,官方称它为"Mark Word"。
  2. 对象头的另外一部分是类型指针,即对象指向它的类型元数据指针,java虚拟机通过指针来确定该对象是哪个类型的实例。如果是数组对象,在对象头中还有一块用于记录数组长度的数据。

实例数据:

  顾名思义,实例数据部分存储的就是实例对象的相关信息了,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来。

对齐填充:

  对象的第三部分是对齐填充,这并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot虚拟机的自动内存管理系统要求对象的起始地址必须是8字节的整数倍,所以

不足8的整数倍就需要补齐。

对象的访问定位:

  创建对象自然是为了后续使用该对象,java虚拟机规范规定java程序通过虚拟机栈的reference来操作堆上的具体对象,各个虚拟机实现的访问方式也不尽相同,主流的访问方式主要使用句柄和直接指针两种,

我们先来看通过句柄的方式访问,如下图:

  通过句柄访问,java堆中会将划分出一块内存来作句柄池,reference中存储的就是对象的句柄地址,句柄中包含了对象实例数据以及类型数据的地址信息。而指针访问的话,

reference中存储的直接就是对象地址,对象实例中同时还需要存指向对象类型数据的指针。如下图所示:

  这两种对象访问方法各有优势,直接指针访问方式,虽然访问访问速度快,但是垃圾回收的效率没有句柄池的效率高。我们常用的HotSpot是使用的直接指针的方式访问对象。

JVM(四)-虚拟机对象的更多相关文章

  1. 深入了解java虚拟机(JVM) 第四章 对象的创建

    一.对象的创建过程 对象的创建过程大致可以分为六步,其中对象的分配尤为重要: 二.对象分配内存 一般来说对象分配内存有两种方式: 第一种是指针碰撞,这是一种比较理想的方式:如果Java堆是绝对规整的: ...

  2. 自制Java虚拟机(四)-对象、new、invokespecial

    自制Java虚拟机(四)-对象.new.invokespecial 一.对象的表示 刚开始学Java的时候,图书馆各种教程,书名往往都是“Java面向对象高级编程”,通常作者都会与C++做个比较,列出 ...

  3. 深入理解JVM(③)——之HotSpot虚拟机对象探秘

    前言 上篇文章介绍了Java虚拟机的运行时数据区域,大致明白了Java虚拟机内存模型的概况,下面就基于实用优先的原则,以最常用的虚拟机HotSpot和最常用的内存区域Java堆为例,升入探讨一下Hot ...

  4. JVM(四):深入分析Java字节码-下

    JVM(四):深入分析Java字节码-下 在上文中,我们讲解了 Class 文件中的文件标识,常量池等内容.在本文中,我们就详细说一下剩下的指令集内容,阐述其分别代表了什么含义,以及 JVM 团队这样 ...

  5. JVM的艺术-对象创建与内存分配机制深度剖析

    JVM的艺术-对象创建与内存分配机制深度剖析 引言 本章将介绍jvm的对象创建与内存分配.彻底带你了解jvm的创建过程以及内存分配的原理和区域,以及包含的内容. 对象的创建 类加载的过程 固定的类加载 ...

  6. 99.9%的Java程序员都说不清的问题:JVM中的对象内存布局?

    本文转载自公众号:石彬的架构笔记,阅读大约需要8分钟. 作者:李瑞杰 目前就职于阿里巴巴,资深 JVM 研究人员 在 Java 程序中,我们拥有多种新建对象的方式.除了最为常见的 new 语句之外,我 ...

  7. java四种对象引用类型

    java四种对象引用类型 对象的强.软.弱和虚引用 在JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象.也就是说,只有对象处于可触及(reachable)状态,程序 ...

  8. JVM常用虚拟机命令汇总

    title: JVM常用虚拟机命令汇总 comments: false date: 2019-07-22 11:45:33 description: 总结一下常用的JVM虚拟机启动命令. catego ...

  9. JVM 堆中对象分配、布局和访问

    本文摘自深入理解 Java 虚拟机第三版 对象的创建 Java 是一门面向对象的语言,Java 程序运行过程中无时无刻都有对象被创建出来.从语言层面看,创建对象只是一个 new 关键字而已,而在虚拟机 ...

随机推荐

  1. python类的封装与继承

    封装 关注公众号"轻松学编程"了解更多. 1.概念 面向对象语言的三大特征:封装, 继承, 多态. 广义的封装: 类和函数的定义本身就是封装的体现. 狭义的封装:一个类的某些属性, ...

  2. #10051 Nikitosh 和异或

    Nikitosh 和异或 其实题意已经简单的不能再简单了,所以就不讲了. 因为题目中 \(1\leq l_1 \leq r_1 <l_2 \leq r_2\leq N\),所以显然对于最终答案, ...

  3. AQS解析

    什么是AQS? AQS是JUC内存的基石,它本质上是一个抽象类,定义了多线程下资源争夺与释放的规则和过程,许多实现类都是继承于AQS,使用AQS的骨架. AQS的原理 AQS总体上来看是由一个FIFO ...

  4. JVM学习(五) -执行子系统

    虚拟机和物理机的区别.两种都有代码执行能力.物理机的执行引擎是建立在处理器.硬件.指令集和操作系统上.而虚拟机的执行引擎是有自己实现的.因此可以自行的制定指令集和执行引擎的结构关系. 个人理解:分为三 ...

  5. How to use vscode to build a springboot project

    How to use vscode to build a springboot project 首先截图一个springboot官网的一个教程说明截图.可以根据这里的指南去创建一个HelloWorld ...

  6. 第一行代码中RecyclerView添加依赖库问题

    现在更新到 implementation 'com.android.support:recyclerview-v7:29.2.1' 记得点Sync Now来进行同步.

  7. 白话科普系列——双十一,竟然是一场有“预谋”的DDoS攻击?

    随著互联网与信息技术的发展,所有人都在享受互联网带来的舒适和便利.如今,无论是个人社交行为,还是商业活动都早已离不开互联网. 但是,网络空间在创造机遇的同时,也带来了威胁.随着企业价值.知名度的提高. ...

  8. 深入Python中的正则表达式

    正则表达式应用的场景也非常多.常见的比如:搜索引擎的搜索.爬虫结果的匹配.文本数据的提取等等都会用到,所以掌握甚至精通正则表达式是一个硬性技能,非常必要. 正则表达式 正则表达式是一个特殊的字符序列, ...

  9. 家庭版window10找不到文件'gpedit.msc'。请确定文件名是否正确后 ,再试一次

    今天遇到电脑找不到gpedit.msc文件,所以记录一下这个问题的解决方法 1. 首先建立一个空白文档  代码如下: @echo off pushd "%~dp0" dir /b ...

  10. Spider--补充--selenium的使用

    # Selenium (firefox) # 1,介绍: # selenium 是一个 web 的自动化测试工具,是一个包,可以支持 C. java.ruby.python.或都是 C# 语言. # ...