概述:

  上一篇文章,介绍了虚拟机类加载的过程,那么类加载好之后,虚拟机下一步该干什么呢。我们知道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. html关键字高亮

    /** * @id 父节点id * @key 关键字 */ function keyLight(id, key, bgColor){ var oDiv = document.getElementByI ...

  2. CentOS下MYSQL数据库的主从备份配置

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/limingzhong198/articl ...

  3. linux下的终端利器----tmux

    转:tmux 是指通过一个终端登录远程主机并运行后,在其中可以开启多个控制台的终端复用软件.类似GNU Screen,但来自于OpenBSD,采用BSD授权.使用它最直观的好处就是,通过一个终端登录远 ...

  4. 深入学习OpenCV文档扫描及OCR识别(文档扫描,图像矫正,透视变换,OCR识别)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 下面 ...

  5. 十个Pycharm快捷键——提升效率

    一些比较实用的Pycharm的快捷键,提升编写开发效率. 1.解除语法限制 默认情况下,Pycharm会对代码进行检查,包括但不仅限于代码是否有语法错误,是否符合PEP8规范. 如命名检查,如下图 变 ...

  6. SpringBoot整合JWT实战详解

    jwt 介绍就不多说了,下面通过代码演示开发过程中jwt 的使用. (1)在pom.xml中引入对应的jar <dependency> <groupId>io.jsonwebt ...

  7. mysql优化之2--索引优化

    1. 创建联合索引时,要注意,离散度大的列前置. 可以通过 select count(distinct(A)),count(distinct(B)) from tb; 看哪个列离散度大. 2. 索引列 ...

  8. 廖师兄springboot微信点餐开发中相关注解使用解释

    package com.imooc.dataobject;import lombok.Data;import org.hibernate.annotations.DynamicUpdate;impor ...

  9. eclipse 和 myeclipse 字符编码设置

    需要设置的几处地方为: Window->Preferences->General ->Content Type 所有 Default encoding 设置为UTF-8 Window ...

  10. [LeetCode题解]141. 环形链表 | 快慢指针

    题目描述 给定一个链表,判断链表中是否有环. 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的 ...