概述:

  上一篇文章,介绍了虚拟机类加载的过程,那么类加载好之后,虚拟机下一步该干什么呢。我们知道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. 一路踩坑,被迫聊聊 C# 代码调试技巧和远程调试

    一:背景 1. 讲故事 每次项目预交付的时候,总会遇到各种奇葩的坑,我觉得有必要梳理一下以及如何快速解决的,让后来人避避坑,这篇就聊聊自己的所闻所遇: 我去,本地环境代码跑的哧溜,上了测试环境出问题 ...

  2. 适合 C++ 新手学习的开源项目——在 GitHub 学编程

    作者:HelloGitHub-小鱼干 俗话说:万事开头难,学习编程也是一样.在 HelloGitHub 的群里,经常遇到有小伙伴询问编程语言如何入门方面的问题,如: 我要学习某一门编程语言,有什么开源 ...

  3. 直播平台源码搭建教程:微信小程序中的直播如何去掉水印

    直播平台源码搭建教程:微信小程序中的直播如何去掉水印 本文与大家分享一下直播平台源码搭建教程,如何去掉直播视频的水印 var services = require('../../lib/service ...

  4. Redis基础—了解Redis是如何做数据持久化的

    之前的文章介绍了Redis的简单数据结构的相关使用和底层原理,这篇文章我们就来聊一下Redis应该如何保证高可用. 数据持久化 我们知道虽然单机的Redis虽然性能十分的出色, 单机能够扛住10w的Q ...

  5. 【软件配置】JDK+AndroidStudio4.1开发安卓APP环境安装和配置教程详细

    目录 一.专业名词 二.搭建前资源准备 2.1 JDK资源下载 2.2 AndroidStudio下载 三.安装 3.1 JDK安装配置 3.2 AndroidStudio安装 四.创建安卓APP工程 ...

  6. CCPC 2020 长春站 部分简略题解

    gym链接:CCPC 2020 changchun site A: 题目大意:商店里有若干个充值档位和首充奖励,你有\(n\)块钱问最多能拿到多少水. 解:由于档位不多可以直接枚举,整个二进制枚举一下 ...

  7. c++中的几种函数调用约定(转)

    C++中的函数调用约定(调用惯例)主要针对三个问题: 1.参数传递的方式(是否采用寄存器传递参数.采用哪个寄存器传递参数.参数压桟的顺序等): 参数的传递方式,最常见的是通过栈传递.函数的调用方将参数 ...

  8. 剑指offer刷题(算法类_1)

    斐波那契数列 007-斐波拉契数列 题目描述 题解 代码 复杂度 008-跳台阶 题目描述 题解 代码 复杂度 009-变态跳台阶 题目描述 题解 代码 复杂度 010-矩形覆盖 题目描述 题解 代码 ...

  9. ceph的rbd备份软件ceph-backup

    teralytics是一家国外的大数据公司,这个是他们开源的ceph的备份的工具,在twitter上搜索相关信息的时候看到,觉得不错就拿来试用一番 这是个什么软件 一个用来备份 ceph 的 rbd ...

  10. linux中KVM桥接网卡br0

    在centos虚拟化当中需要增加一个桥接网卡,然后将虚拟化当中的机器的网卡桥接到桥接网卡,下面将描述设置方法: 查看现有网卡 [root@zb ~]# vim /etc/sysconfig/netwo ...