JVM进阶之路(三)探究虚拟机对象

java的深入探究JVM之内存结构 前言Java作为一种平台无关性的语言,其主要依靠于Java虚拟机——JVM,我们写好的代码会被编译成class文件,再由JVM进行加载、解析、执行,而JVM有统一的规范,所以我们不需要像C++那样需要程序员自己关注平台,大大方便了我们的开发。另外,能够运行在JVM上的并非只有Java,只要能够编译生成合乎规范的class文件的语言都是可以跑在JVM上的。而作为一名Java开发,JVM是我们必须要学习了解的基础,也是通向高级及更高层次的必修课;但JVM的体系非常庞大,且术语非常多,所以初学者对此非常的头疼。 阅读详情

1、对象创建过程

单纯从语言层面,新建一个对象,可以通过new、反射、复制、反序列化等等。接下来,我们探究以下在虚拟机中,对象的创建是一个什么样的过程。

我们以虚拟机遇到一个new指令开始:

  • 首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用

  • 检查这个符号引用代表的类是否已被加载、解析和初始化过。如果没有,就先执行相应的类加载过程

  • 类加载检查通过后,接下来虚拟机将为新生对象分配内存。

    内存分配有两种方式,指针碰撞(Bump The Pointer)、空闲列表(Free List)

    • 指针碰撞:假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”
    • 如果Java堆中的内存并不是规整的,已被使用的内存和空闲的内存相互交错在一起,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录,这种分配方式称为“空闲列表”
    • 两种方式的选择由Java堆是否规整决定
    • Java堆规整由所采用的垃圾收集器是否带有空间压缩整理(Compact)的能力决定
  • 内存分配完成之后,虚拟机将分配到的内存空间(但不包括对象头)都初始化为零值。

  • 接下来设置对象头,请求头里包含了对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。

这个过程大概图示如下:

对象创建过程

分配内存线程安全问题:对象创建在虚拟机中是非常频繁的行为,即使仅仅修改一个指针所指向的位置,在并发情况下也并不是线程安全的,可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。

线程安全问题有两种解可选方案:

  • 一种是对分配内存空间的动作进行同步处理——实际上虚拟机是采用CAS配上失败重试的方式保证更新操作的原子性
  • 另外一种是把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,只有本地缓冲区用完了,分配新的缓存区时才需要同步锁定。

从虚拟机角度来看,设置完对象头信息以后初始化就已经完成了,但是对于Java程序而言,new指令之后会接着执行<init> ()方法,对对象进行初始化,这样一个真正可用的对象才算完全被构造出来。

new->init

2、对象的内存布局

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

对象的内存布局

HotSpot虚拟机对象的对象头部分包括两类信息。第一类是用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32个比特和64个比特,官方称它为“Mark Word”。

考虑到虚拟机的空间效率,Mark Word被设计成一个有着动态定义的数据结构,以便在极小的空间内存储尽量多的数据,根据对象的状态复用自己的存储空间。

例如在64位的HotSpot虚拟机中,如对象未被同步锁锁定的状态下,Mark Word的64个比特存储空间中的31个比特用于存储对象哈希码,4个比特用于存储对象分代年龄,2个比特用于存储锁标志位,在其他状态(轻量级锁、重量级锁、偏向锁)下对象的存储内容变化如图示。

64虚拟机Mark World

对象头的另外一部分是类型指针,即对象指向它的类型元数据的指针,Java虚拟机通过这个指针来确定该对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,查找对象的元数据信息并不一定要经过对象本身,

如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是如果数组的长度是不确定的,将无法通过元数据中的信息推断出数组的大小。

3、对象的访问定位

Java程序会通过栈上的reference数据来操作堆上的具体对象。由于reference类型在《Java虚拟机规范》里面只规定了它是一个指向对象的引用,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实现而定的,主流的访问方式主要有使用句柄和直接指针两种:

  • 如果使用句柄访问的话,Java堆中将可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息,其结构如图所示:

通过句柄访问对象

  • 如果使用直接指针访问的话,Java堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息,reference中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销,如图所示:

通过直接指针访问对象

这两种对象访问方式各有优势,使用句柄来访问的最大好处就是reference中存储的是稳定句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要被修改。

使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访问在Java中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本。

HotSpot虚拟机主要使用直接指针来进行对象访问。

一文带你搞懂JVM虚拟机的内存区域划分 阅读详情

相关推荐

必看!wechat-article-exporter:轻松批量下载公众号文章

微信搜索“”关注公众号。在信息爆炸的时代,我们每天都会接触到大量优秀的微信公众号文章。有时候,我们想要将这些精彩的内容保存下来,以便日后回顾或者分享给更多的人。然而,微信公众号并没有提供直接的批量下载功能,这给我们带来了不少困扰。今天,我要给大家分享一款非常实用的软件——wechat-article-exporter,它能够帮助我们轻松地批量下载微信公众号文章,让你不再为文章的保存而烦恼。

王乐平 技术博客 4347

JVM虚拟机

JVM是的简称,意为Java虚拟机。虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。常见的虚拟机:JVMVMwave。JVM 和其他两个虚拟机的区别:VMwave与VirtualBox是通过软件模拟物理CPU的指令集,物理系统中会有很多的寄存器;JVM则是通过软件模拟Java字节码的指令集,JVM中只是主要保留了PC寄存器,其他的寄存器都进行了裁剪。JVM是一台被定制过的现实当中不存在的计算机。

qq_64580912的博客 4293

SecureCRT串口连接保姆级教程:从驱动安装到波特率设置(附常见问题解决)

本文提供SecureCRT串口连接的保姆级教程,涵盖从USB转串口驱动安装、端口识别到波特率等核心参数设置的完整流程。针对连接失败、乱码、键盘输入无响应等高频问题,给出了深度排查与解决方案,帮助网络与嵌入式开发新手快速掌握串口调试技能。

weixin_29281941的博客 431

JVM(Java虚拟机)

JVM 是 Java Virtual Machine 的简称,意为 Java虚拟机。虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。常见的虚拟机:JVM、VMwave、Virtual Box。1. VMwave与VirtualBox是通过软件模拟物理CPU的指令集,物理系统中会有很多的寄存器;2. JVM则是通过软件模拟Java字节码的指令集,JVM中只是主要保留了PC寄存器,其他的寄存器都进 行了裁剪。JVM 是一台被定制过的现实当中不存在的计算机。

qq_59561046的博客 3389

Windows下的Geant4安装教程

本教程将从0开始展示在Windows下如何安装Geant4,包括各种辅助工具(QT、Cmake、Visual Studio)的下载安装,环境变量的配置,以及example的生成等。

weixin_49065278的博客 4096

国产麒麟系统PXE安装-UEFI引导

注意: 适用uefi引导 适用x86_64架构 一键部署脚本扣我 1.上传ISO到PXE服务器,拷贝ISO文件 # mkdir /kylin_iso # mount -o loop Kylin-Server-10-SP1-Release-Build04-20200711-x86_64.iso /kylin_iso/ 2.配置http,获取安装源 # yum -y install httpd # mkdir /var/www/html/{ks,kylin} # 注意一定是"/kylin_iso/

河静 5051

JVM(java虚拟机)

JVM是JavaVirtualMachine(Java虚拟机)的缩写,是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟计算机功能来实现的,JVM屏蔽了与具体操作系统平台相关的信息,Java程序只需生成在Java虚拟机上运行的字节码,就可以在多种平台上不加修改的运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。

yyc021204的博客 4041

电路设计仿真软件:Mentor Graphics_(11).MentorGraphics软件操作与技巧

/ 定义自定义仿真命令// 加载设计文件// 运行仿真// 主函数return 1;return 0;// 自定义设计检查// 获取设计中的所有模块// 遍历所有模块// 检查模块名称是否符合规范if (!// 检查模块中的所有引脚if (!// 主函数main() {通过本节的学习,您应该已经掌握了如何在 Mentor Graphics 中进行二次开发,包括使用 Tcl、C++ 和 Python 进行基本和高级操作。

kkchenjj的博客 1635

JVM——Java虚拟机详解

内存分配有两种方式,指针碰撞空闲列表指针碰撞和空闲列表指针碰撞:假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离,这种分配方式称为“指针碰撞”。

qq_43842093的博客 3074

华为OD机考2025C卷 - 精准核酸检测(Java & Python& JS & C++ & C语言)

华为OD机考2025C卷 - 精准核酸检测,提供在线OJ Java & Python& JS & C++ & C

算法大师! 2879

NR PUCCH(一) PUCCH format 0/1

NR中PUCCH物理信道用来发送上行控制信息Uplink Control Information(UCI),当然UCI也可以在PUSCH上发送。UCI 内容包括:CSI,HARQ ACK/NACK ,SR 及上述三者的组合信息。 那先看下PUCCH format ,序列的生成及资源映射的相关内容。 NR中支持5种格式PUCCH,根据PUCCH format占用时域符号长度分为短PUCCH(1-2个符号,PUCCH 0/2)和长PUCCH(4-14个符号,PUCCH1/3/4)。使用短PUCCH 能够支

asd199086的博客 6058

【JVM进阶之路】三:探究虚拟机对象

JVM进阶之路第三篇,探究对象创建过程和内存布局。

三分恶的博客 3639

基于转录逆转的药物重定向 GPS 模型

GPS是一个基于分子结构预测基因表达扰动的开源平台,由三个模块组成:RCL(在LINCS扰动数据上训练抗噪MLP)、GPS4Drugs(预测新化合物的基因表达谱并进行逆转评分)、MolSearch(基于MCTS的分子优化)。平台使用Morgan指纹和Gene Ontology注释作为特征输入,将基因表达扰动离散为三分类标签。训练数据来自LINCS Phase I的18,746个化合物和978个landmark基因,支持四细胞系独立训练,可用于药物重定向与化合物筛选。

听雨草堂 81

Java对象与JVM(一) Java对象在Java虚拟机中的创建过程

下面我们详细了解Java程序中new一个普通对象时,HotSpot虚拟机是怎么样创建这个对象的,包括5个步骤:相应类加载检查过程、在Java堆中为对象分配内存、分配后内存初始化为零、对对象进行必要的设置、以及执行对象实例方法,最后我们再从JVM指令角度来解释下Java对象创建。

tjiyu的博客 1万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

JVM虚拟机详解

不了解JVM的Java程序员无异于蒙上双眼在沼泽地奔跑的犀牛,你永远不知道你会在什么时候会掉进坑里,也永远不会明白为什么会掉进坑里。 那么,今天你是蒙着双眼奔跑的么?

Baldwin_KeepMind 9217

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【JVM进阶之路】一:Java虚拟机概览

JVM进阶之路第一篇,介绍Java虚拟机。

三分恶的博客 4139

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

三、jvm中的对象及引用

检查加载-->分配内存-->内存空间初始化-->设置-->对象初始化。

空杯 1265

JVM中的对象探秘(三)- 对象的实例数据与对齐填充

引言 上一篇文章我们讲解了JVM对象内存布局的第一部分对象头,今天我们继续来讲讲剩下的两部分实例数据(Instance Data) 、对齐填充(Padding)。 实例数据与对齐填充 这两部分我们放在一起将,先来看一下概念(深入理解JAVA虚拟机 第2.3.2节): 实例数据(Instance Data): 实例数据部分是对象真正存储的有效信息,也既是我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的都需要记录下来。 这部分的存储顺序会受到虚拟机分配策略参数Fiel

q13145241q的博客 3573

JVM虚拟机-探究Java内存区域与对象创建过程

JVM虚拟机-探究Java内存区域与对象创建过程 欢迎访问我的个人博客 参考书籍:《深入理解JAVA虚拟机》 这里写目录标题JVM虚拟机-探究Java内存区域与对象创建过程1.概述2.运行时数据区域2.1.程序计数器2.2.Java虚拟机栈2.3.本地方法栈2.4.Java堆2.5.方法区2.6.运行时常量池3.HotSpot虚拟机对象探秘3.1.对象的创建3.2.对象的内存布局3.3.对象的访问定位4.本文知识点思维导图(原图可私信) 1.概述 对于Java程序来说,在虚拟机自动内存管理机制的帮助下,不

weixin_43265151的博客 444

jvm对象探究

jvm基础知识

m0_74347016的博客 434

JVM01_概述、跨平台原理、分类、三大商业虚拟机

前言: 判断对象存活的两种方式(引用计数算法、枚举根节点做可达性分析) ①. 引用计数法 ①. 原理:假设有一个对象A,任何一个对象对A的引用,那么对象A的引用计数器+1,当引用失败时,对象A的引用计数器就-1,如果对象A的计数器的值为0,就说明对象A没有引用了,可以被回收 ②. 最大的缺陷:无法解决循环引用的问题,gc永远都清除不了(这也是引用计数法被淘汰的原因) ③. 代码展示: /** * -XX:+PrintGCDetails * 证明:java使用的不是引用计数算法 */.

所得皆惊喜 6375

JVM三JVM虚拟机

考虑到虚拟机的空间效率,Mark Word被设计成一个非固定的数据结构,以便在极小的空间内,尽量多的存储数据,它会根据对象的状态复用自己的存储空间,也就是说,Mark Word会随着程序的运行发生变化,变化状态如下(JDK1.8)。当对象大于TLAB中的剩余内存或TLAB的内存已用尽时,再采用上述的CAS进行内存分配。:当新生代无法分配内存的时候,我们想把新生代的老对象转移到老年代,然后把新对象放入腾空的新生代。实例数据(Instance Data):生成对象的时候,对象的非静态成员变量也会存入堆空间。

蜗牛跑的快 921

Java进阶-JVM虚拟机原理

1,什么是JVM虚拟机呢? JVM是java虚拟机的一个缩写, jvm是一种"用于计算设备的规范",它是人们虚拟出来的计算机,是人们模仿各种计算机计算功能来实现的.Java虚拟机包含 一套字节码的指令集,一组寄存器,一个栈,一个垃圾回收堆,一个储存方法区.JVM屏蔽了与具体操作系统平台的相关信息,使Java程序员只需要生成再Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改的运...

classabcd的博客 801

JVM学习总结(三):深入探究JVM中的对象及引用

前言 正文 一、对象的创建过程 1、类加载 类加载就是把 class 加载到 JVM 的运行时数据区的过程(类加载后续会详细讲)。 2、检查加载 首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用(符号引用 :符号引用以一组符号来描述所引用的目标),并且检查类是否已经被加载、解析和初始化过。 3、分配内存 接下来虚拟机将为新生对象分配内存。为对象分配空间的任务等同于把一块确定大小的内存从 Java 堆中划分出来。 3.1 内存分配方式 指针碰撞 如果 Java 堆中内存是绝对规整的,所有用过的

weixin_42208959的博客 613

jvm虚拟机-什么是jvm

最近看了一段时间jdk源码,在看源码的过程中对数据的存储不是很清楚,当时就在想数据到底存在哪里去了?以前只是看博客什么的对jvm有一个大概的了解,但是没有深入研究。经过一段时间的研究<<深入理解java虚拟机后>>,才决定写一些关于jvm的文章,不为别的只为了同为技术的程序员们少走一些弯路,因为这本书第一遍读起来晦涩难懂,我也是查阅了大量的资料才渐渐的理解了什么意思。同时也为了留下自己的脚印,以后几

wenhao_1992的博客 5856
上一篇: JVM进阶之路(二)Java内存区域
下一篇: JVM进阶之路(四)直面内存溢出和内存泄漏
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值