当前位置: 首页 > news >正文

JVM原理(二):JVM之HotSpot虚拟机中对象的创建寻位与定位整体流程

1. 对象的创建

遇到new指令时

当Java虚拟机遇到一个字节码new指令时。

首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。

如果没有,那么必须执行类的加载过程(加载、检查、准备、解析、初始化)

类加载后?

类加载检查通过后,接下来虚拟机会为新生对象分配内存。对象所需内存的大小在类加载完成后便可完全确定

划分内存:

  1. 如果Java堆中内存是绝对规整的,那么只需一个指针作为分界点的指示器,对象需要多少内存,就移出多少内存。我们称这种方式为指针碰撞

  2. 如果Java堆中的内存不是规整的,那么虚拟机就必须维护一个表,记录那些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表的记录,这种分配方式称为空闲列表

分配安全

在线程并发情况下,可能会出现正在给对象A分配一块内存,但指针还没来得及修改,对象B又使用了原来的指针进行分配,这就会造成内存不安全。

  1. 解决方案1:对分配内存空间的操作进行同步处理——实际上虚拟机是采用CAS配上失败重试的方式保证更新操作的原子性。

  2. 解决方案2:把内存分配的动作按照线程划分在不同空间之中进行,即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(TLAB)

分配内存之后该怎么做?

Java虚拟机会将必要的信息存放到对象的对象头中,其中包括这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄信息等。

分配好对象头之后,对象创建才刚刚开始(Java程序的角度)

目前对象的构造函数,即Class文件中的<init>()方法还没执行,所有的字段都为默认的零值,对象需要的其他资源和状态信息也还没有按照预定的意图构造好。new指令之后会接着执行<init>()方法,按照程序员的意愿对对象进行初始化,这样一个真正可用的对象才算完全被构造出来。

2. 对象的内存布局

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


对象头结构

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

第一类是用于存储对象自身的运行时数据,如哈希码(HashCode) 、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,官方称它为“MarkWord?。MarkWord被设计成一个有着动态定义的数据结构。

        对象头的另外一部分是类型指针,即对象指向它的类型元数据的指针,Java虛拟机通过这个指针来确定该对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身,这点我们会在下一节具体讨论。此外,如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是如果数组的长度是不确定的,将无法通过元数据中的信息推断出数组的大小。


对象第二部分数据(内存)

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


对象第三部分

对象的第三部分是对齐填充,这并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是任何对象的大小都必须是8字节的整数倍。对象头部分已经被精心设计成正好是8字节的倍数(1倍或者2倍),因此,如果对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。

3. 对象的访问定位

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

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

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


两者的区别

使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访问在Java中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本,就本书讨论的主要虚拟机HotSpot而言,它主要使用第二种方式进行对象访问。

相关文章:

JVM原理(二):JVM之HotSpot虚拟机中对象的创建寻位与定位整体流程

1. 对象的创建 遇到new指令时 当Java虚拟机遇到一个字节码new指令时。 首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用&#xff0c;并且检查这个符号引用代表的类是否被加载、解析和初始化过。 如果没有&#xff0c;那么必须执行类的加载过程(加载、检查…...

(七)glDrawArry绘制

几何数据&#xff1a;vao和vbo 材质程序&#xff1a;vs和fs(顶点着色器和片元着色器) 接下来只需要告诉GPU&#xff0c;使用几何数据和材质程序来进行绘制。 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostrea…...

记一次小程序渗透

这次的小程序渗透刚好每一个漏洞都相当经典所以记录一下。 目录 前言 漏洞详情 未授权访问漏洞/ 敏感信息泄露&#xff08;高危&#xff09; 水平越权&#xff08;高危&#xff09; 会话重用&#xff08;高危&#xff09; 硬编码加密密钥泄露&#xff08;中危&#xff0…...

C++ 的常见算法 之一

C 的常见算法 之一 不修改序列算法for_eachcountfind 修改序列算法copymove 不修改序列算法 for_each #include <iostream> // std::cout #include <algorithm> // std::for_each #include <vector> // std::vectorusing namespace std;struc…...

微前端的需求有哪些?微前端的原理是怎么样的?为什么这么设计,及微前端的应用场景是什么?对有些客户,前端的重要性高于后端

微前端&#xff08;Micro Frontends&#xff09;是将前端应用拆分成多个独立、可部署的部分&#xff0c;每个部分可以由不同的团队独立开发、测试、部署和维护。这种架构类似于微服务在后端的应用&#xff0c;是为了应对复杂前端应用的维护和扩展问题而提出的。 来龙去脉 背景…...

【Spring Boot】统一数据返回

目录 统一数据返回一. 概念二.实现统一数据返回2.1 重写responseAdvice方法2.2 重写beforeBodyWriter方法 三. 特殊类型-String的处理四. 全部代码 统一数据返回 一. 概念 其实统一数据返回是运用了AOP&#xff08;对某一类事情的集中处理&#xff09;的思维&#xff0c;简单…...

证券交易系统中服务器监控系统功能设计

1.背景介绍 此服务器监控系统的目的在于提高行情服务器的监管效率&#xff0c;因目前的的行情服务器&#xff0c;包括DM、DT、DS配置数量较多&#xff0c;巡回维护耗时较多&#xff0c;当行情服务器出现异常故障&#xff0c;或者因为网络问题造成数据断线等情况时&#xff0c;监…...

【线性代数的本质】矩阵与线性变换

线性变化要满足两点性质&#xff1a; 直线&#xff08;连续的点&#xff09;在变换后还是直线。原点不变。 假设有坐标轴&#xff08;基底&#xff09; i ^ \widehat{i} i 和 j ^ \widehat{j} j ​&#xff1a; i ^ [ 1 0 ] , j ^ [ 0 1 ] \widehat{i}\begin{bmatrix} 1 \…...

CV02_超强数据集:MSCOCO数据集的简单介绍

1.1 简介 MSCOCO数据集&#xff0c;全称为Microsoft Common Objects in Context&#xff0c;是由微软公司在2014年推出并维护的一个大规模的图像数据集&#xff0c;旨在推动计算机视觉领域的研究&#xff0c;尤其是目标识别、目标检测、实例分割、图像描述生成等任务。该数据集…...

Linux--信号(万字详解!超完整!)

目录 0.预备知识 0.1.基本概念 0.2.信号的捕捉 0.3.理解信号的发送与保存 1.信号的产生&#xff08;阶段一&#xff09; 1.通过kill命令&#xff0c;向指定进程发送指定的信号 2.通过终端按键产生信号&#xff1a;ctrlc&#xff08;信号2&#xff09;&#xff0c;ctrl\(…...

onnx模型转rknn到部署

简介 最近开始用3568的板子&#xff0c;之前是在用3399&#xff0c;cpu的话3399比3568强&#xff0c;但是3568有1T的npu算力&#xff0c;所以模型移植过来用npu使用&#xff0c;之前用ncnn感觉太慢了&#xff0c;rk的npu使用没有开源&#xff0c;所以没法兼容&#xff0c;只能跑…...

lua入门(1) - 基本语法

本文参考自&#xff1a; Lua 基本语法 | 菜鸟教程 (runoob.com) 需要更加详细了解的还请参看lua 上方链接 交互式编程 Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。 Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用&#xff1a; 如下图: 按…...

Finding Global Homophily in Graph Neural Networks When Meeting Heterophily

本文发表于:ICML22 推荐指数: #paper/⭐⭐⭐ 问题背景: 异配图的邻接矩阵难以确定,以及异配图的计算复杂度开销大 可行的解决办法:高通滤波多跳邻居,GPRGNN(pagerank一类&#xff0c;各阶邻居的权重不同,ACM-GCN&#xff08;高低通滤波,H2GCN&#xff08;应该复杂度很大&…...

DisFormer:提高视觉动态预测的准确性和泛化能力

最新的研究进展已经显示出目标中心的表示方法在视觉动态预测任务中可以显著提升预测精度&#xff0c;并且增加模型的可解释性。这种表示方法通过将视觉场景分解为独立的对象&#xff0c;有助于模型更好地理解和预测场景中的变化。 尽管在静态图像的解耦表示学习方面已经取得了一…...

Android SurfaceFlinger——Surface和Layer介绍(十九)

按照前面系统开机动画的流程继续分析,在获取到显示屏信息后,下一步就是开始创建 Surface和设置 Layer 层级,这里就出现了两个新的概念——Surface 和 Layer。 一、基本概念 1、Surface介绍 在 Android 系统中,Surface 是一个非常核心的概念,它是用于显示图像的生产者-消…...

C++基础(七):类和对象(中-2)

上一篇博客学的默认成员函数是类和对象的最重要的内容&#xff0c;相信大家已经掌握了吧&#xff0c;这一篇博客接着继续剩下的内容&#xff0c;加油&#xff01; 目录 一、const成员&#xff08;理解&#xff09; 1.0 引入 1.1 概念 1.2 总结 1.2.1 对象调用成员函数 …...

对秒杀的思考

一、秒杀的目的 特价商品&#xff0c;数量有限&#xff0c;先到先得&#xff0c;售完为止 二、优惠券的秒杀 和特价商品的秒杀是一样的&#xff0c;只不过秒杀的商品是优惠券 三、秒杀的需求 秒杀前&#xff1a;提前将秒杀商品&#xff0c;存放到Redis秒杀中&#xff1a;使…...

数据结构预科

在堆区申请两个长度为32的空间&#xff0c;实现两个字符串的比较【非库函数实现】 要求&#xff1a; 1> 定义函数&#xff0c;在对区申请空间&#xff0c;两个申请&#xff0c;主函数需要调用2次 2> 定义函数&#xff0c;实现字符串的输入&#xff0c;void input(char …...

想做亚马逊测评技术需要解决哪些问题,有哪些收益?

现在真正有亚马逊测评技术的人赚的盆满钵满&#xff0c;有些人看到别人赚取就自己盲目去做&#xff0c;买完了账号和设备就感觉自己懂了&#xff0c;却不知里面的水深着&#xff0c;花了钱却没有掌握真正的技术&#xff0c;号莫名其妙就封完了&#xff0c;而每一次大风控注定要…...

1117 数字之王

solution 判断现有数字是否全为个位数 全为个位数&#xff0c;找出出现次数最多的数字&#xff0c;并首行输出最多出现次数&#xff0c;第二行输出所有出现该次数的数值不全为个位数 若当前位数值为0&#xff0c;无需处理若当前位数值非0&#xff0c;则每位立方相乘&#xff0…...

ai辅助c++开发:让快马成为你的codeblocks智能编程助手与算法导师

AI辅助C开发&#xff1a;让快马成为你的CodeBlocks智能编程助手与算法导师 最近在用CodeBlocks开发一个C图形化应用时&#xff0c;遇到了一个典型问题&#xff1a;需要实现非递归快速排序算法并测试性能。传统开发方式可能需要反复查阅文档、调试代码&#xff0c;但借助InsCod…...

基于Ascend 950的Cube编程

直播回放链接&#xff1a;基于下一代硬件的Cube编程_哔哩哔哩_bilibili...

Qwen-Image-Edit-F2P在Vue前端项目中的可视化应用

Qwen-Image-Edit-F2P在Vue前端项目中的可视化应用 1. 引言 想象一下这样的场景&#xff1a;用户上传一张简单的人脸照片&#xff0c;几秒钟后就能看到自己穿着优雅礼服站在巴黎街头&#xff0c;或是化身古风侠客执剑而立。这种曾经只存在于科幻电影中的体验&#xff0c;现在通…...

电话号码定位技术:三步实现手机号码精准定位的终极指南

电话号码定位技术&#xff1a;三步实现手机号码精准定位的终极指南 【免费下载链接】location-to-phone-number This a project to search a location of a specified phone number, and locate the map to the phone number location. 项目地址: https://gitcode.com/gh_mir…...

Git Diff View:三分钟学会实用的代码差异对比组件

Git Diff View&#xff1a;三分钟学会实用的代码差异对比组件 【免费下载链接】git-diff-view A Diff View component for React / Vue, just like Github 项目地址: https://gitcode.com/gh_mirrors/gi/git-diff-view 你是否曾经在代码审查中为理解复杂的Git差异而头疼…...

ESP32-S3 开发实战:从问题排查到功能优化

1. ESP32-S3开发环境搭建与常见问题 刚拿到ESP32-S3开发板时&#xff0c;我最先遇到的就是环境配置问题。这里分享几个新手容易踩的坑&#xff1a;首先是开发工具链的选择&#xff0c;官方推荐使用ESP-IDF或Arduino IDE。我建议初学者先用Arduino IDE上手&#xff0c;因为它的库…...

LeetCode 300. Longest Increasing Subsequence 题解

LeetCode 300. Longest Increasing Subsequence 题解 题目描述 给你一个整数数组 nums&#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;…...

J1712-粒状巧克力糖包装机设计【颗粒状糖果包装机设计】【三维SW模型+6张CAD图纸+说明】

J1712-粒状巧克力糖包装机设计【颗粒状糖果包装机设计】【三维SW模型6张CAD图纸说明】 传送带电机刚启动那会儿&#xff0c;总有几个巧克力豆卡在导流槽边缘。凌晨三点的实验室里&#xff0c;我盯着SolidWorks里旋转的螺旋送料机构模型&#xff0c;突然意识到——这玩意儿得做成…...

Cursor Pro免费激活指南:3步解锁AI编程工具的完整功能

Cursor Pro免费激活指南&#xff1a;3步解锁AI编程工具的完整功能 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached your tri…...

AAC编码详解

嵌入式音视频开发——AAC编码 1. AAC 编码概述 在嵌入式音视频开发中&#xff0c;AAC&#xff08;Advanced Audio Coding&#xff0c;高级音频编码&#xff09;是一种非常常见的有损音频压缩技术&#xff0c;广泛应用于手机、机顶盒、车机、智能摄像头、会议终端、对讲设备以及…...