java虚拟机中对象创建过程
java虚拟机中对象创建过程
我们平常创建一个对象,仅仅只是使用new关键字new一个对象,这样一个对象就被创建了,但是在我们使用new关键字创建对象的时候,在java虚拟机中一个对象是如何从无到有被创建的呢,我们接下来就来谈谈在java虚拟机中一个对象的创建过程(仅指我们平常使用的对象,不包括数组对象和Class对象)。
对象的内存布局
在了解对象的创建过程之前,我们先说说对象的内存布局,在HotSpot虚拟机中,对象在堆中的存储布局可以划分为三部分:对象头(Header)、示例数据(Instance Data)和对齐填充(Padding)。
对象头(Header)
HotSpot虚拟机对象的对象头包括两类信息。
第一类是用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。
对象头的另一部分是类型指针,即对象指向它的类型元数据的指针,java虚拟机通过这个指针来确定该对象是哪个类的实例。
如果对象是一个Java数组,那在对象头中还必须有一块用于记录数组长度的数据,因为虚拟机可以通过普通Java对象的元数据信息确定Java对象的大小,但是如果数组的长度是不确定的,将无法通过元数据信息推断出数组的大小。
实例数据(Instance Data)
这部分是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的自读那都必须记录起来。这部分的存储顺序会 受到虚拟机分配策略参数(-XX:FieldsAllocationStyle参数)和字段在Java源码中定义顺序的影响。 HotSpot虚拟机默认的分配顺序为longs/doubles、ints、shorts/chars、bytes/booleans、oops(Ordinary Object Pointers,OOPs)。
如果HotSpot虚拟机的 +XX:CompactFields参数值为true(默认就为true),那子类之中较窄的变量也允许插入父类变量的空 隙之中,以节省出一点点空间。
对齐填充(Padding)
这部分不是必须存在的,也没有特殊的意义,它仅仅起到占位符的作用。
由于HotSpot虚拟机的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说就是 任何对象的大小都必须是8字节的整数倍。对象头部分已经被精心设计成正好是8字节的倍数(1倍或者 2倍),因此,如果对象实例数据部分没有对齐的话,就需要通过对齐填充来补全。
对象的创建
当Java虚拟机遇到一条字节码new指令时,会首先去检查这个指令的参数是否能正常在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化过。如果没有那必须先执行相应的类加载过程。类加载过程可以看这篇文章。
在类加载完成后对象所需的内存大小便已经确定,接下来就是给新对象在java堆中分配存储空间,这个过程相当于是将一块确定大小的内存块从java堆中划分出来,这个过程有两种方式:
-
指针碰撞
这种方式适用于Java堆中的内存空间是规整的情况,这种情况下被使用的内存在一边,空闲的空间在另一边,中间放着一个指针作为分界点的指示器,这种情况下分配内存就只是将中间的指针向空闲空间的方向移动一段与对象大小相等的距离即可。
-
空闲列标
这种方式适用于Java堆中的内存空间是不规整的情况,这种情况下适用过的内存和空闲的内存交错在一起,这样就不能使用简单的指针碰撞来给对象分配内存了。此时虚拟机维护了一个列表,记录了哪些内存块是可用的,在给对象分配内存时,从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录即可。
内存分配完成之后,虚拟机必须将分配到的内存空间(但不包括对象头)都初始化为零值。这步保证了对象的实例字段在Java代码可以不赋初值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
接下来,Java虚拟机还要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到 类的元数据信息、对象的哈希码(实际上对象的哈希码会延后到真正调用Object::hashCode()方法时才 计算)、对象的GC分代年龄等信息。这些信息存放在对象的对象头(Object Header)之中。
在上面的工作完成之后,从虚拟机的角度来看,一个新的对象已经产生了。但是从Java程序的角度来看,对象的创建才刚刚开始,因为构造函数(即Class文件中的init方法)还没有执行,所有的字段都还是默认的零值。一般来说,new指令之后会接着执行 ()方法,按照程序员的意愿对对象进行初始化,这样一个真正可用的对象才算完全被构造出来。
对象的访问定位
创建对象自然是为了后续使用该对象,我们的Java程序会通过栈上的reference数据来操作堆上的具 体对象。对象的访问方式是由虚拟机实现而定的,主流的访问方式有使用句柄和直接指针两种。
句柄访问
如果使用句柄访问的话,Java堆中将可能会划分出一块内存来作为句柄池,reference中存储的就 是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息。

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

这两种对象访问方式都各有优势,使用句柄访问的最大好处就是reference中存储的时稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不会被修改。
使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访 问在Java中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本。
相关文章:
java虚拟机中对象创建过程
java虚拟机中对象创建过程 我们平常创建一个对象,仅仅只是使用new关键字new一个对象,这样一个对象就被创建了,但是在我们使用new关键字创建对象的时候,在java虚拟机中一个对象是如何从无到有被创建的呢,我们接下来就来…...
3485. 最大异或和
Powered by:NEFU AB-IN Link 文章目录3485. 最大异或和题意思路代码3485. 最大异或和 题意 给定一个非负整数数列 a,初始长度为 N。 请在所有长度不超过 M的连续子数组中,找出子数组异或和的最大值。 子数组的异或和即为子数组中所有元素按位异或得到的…...
SpringBoot:SpringBoot配置文件.properties、.yml 和 .ymal(2)
SpringBoot配置文件1. 配置文件格式1.1 application.properties配置文件1.2 application.yml配置文件1.3 application.yaml配置文件1.4 三种配置文件优先级和区别2. yaml格式2.1 语法规则2.2 yaml书写2.2.1 字面量:单个的、不可拆分的值2.2.2 数组:一组按…...
QT 学习之QPA
QT 为实现支持多平台,实现如下类虚函数 Class Overview QPlatformIntegration QAbstractEventDispatcherQPlatformAccessibilityQPlatformBackingStoreQPlatformClipboardQPlatformCursorQPlatformDragQPlatformFontDatabaseQPlatformGraphicsBufferQPlatformInput…...
Pytorch中FLOPs和Params计算
文章目录一. 含义二. 使用thop库计算FLOPs和Params三. 注意四. 相关链接一. 含义 FLOPs(计算量):注意s小写,是floating point operations的缩写(这里的小s则表示复数),表示浮点运算数ÿ…...
DP1621国产LCD驱动芯片兼容替代HT1621B
目录DP1621简介DP1621芯片特性DP1621简介 DP1621是点阵式存储映射的LCD驱动器芯片,可支持最大128点(32SEG * 4COM)的 LCD屏,也支持2COM和3COM的LCD屏。单片机可通过3/4个通信脚配置显示参数和发送显示数据,也可通过指…...
Linux 用户管理
用户管理 useradd新增用户 格式:useradd [参数] 用户名称 常用参数: -c comment 指定一段注释性描述。 -d 目录 指定用户主目录,如果此目录不存在,则同时使用-m选项,可以创建主目录。 -g 用户组 指定用户所属的用户组…...
前端vue面试题(持续更新中)
vue-router中如何保护路由 分析 路由保护在应用开发过程中非常重要,几乎每个应用都要做各种路由权限管理,因此相当考察使用者基本功。 体验 全局守卫: const router createRouter({ ... }) router.beforeEach((to, from) > {// .…...
Java查漏补缺-从入门到精通汇总
Java查漏补缺(01)计算机的硬件与软件、软件相关介绍、计算机编程语言、Java语言概述、Java开发环境搭建、Java开发工具、注释、API文档、JVM Java查漏补缺(02)关键字、标识符、变量、基本数据类型介绍、基本数据类型变量间运算规…...
软件测试2年半的我,谈谈自己的理解...
软件测试两年半的我,谈谈自己的理解从2020年7月毕业,就成为一名测试仔。日子混了一鲲年,感觉需要好好梳理一下自己的职业道路了,回顾与总结下吧。一、测试的定位做事嘛,搞清楚自己的定位很重要。要搞清楚自己的定位&am…...
什么是SAS硬盘
什么是SAS硬盘SAS是新一代的SCSI技术,和Serial ATA(SATA)硬盘都是采用串行技术,以获得更高的传输速度,并通过缩短连结线改善内部空间等。SAS是并行SCSI接口之后开发出的全新接口。此接口的设计是为了改善存储系统的效能、可用性和扩充性&…...
一文理解服务端渲染SSR的原理,附实战基于vite和webpack打造React和Vue的SSR开发环境
SSR和CSR 首先,我们先要了解什么是SSR和CSR,SSR是服务端渲染,CSR是客户端渲染,服务端渲染是指 HTTP 服务器直接根据用户的请求,获取数据,生成完整的 HTML 页面返回给客户端(浏览器)展…...
Matlab 实用小函数汇总
文章目录Part.I 元胞相关Chap.I 创建空 char 型元胞Part.II 矩阵相关Chap.I 矩阵插入元素Part.III 字符串相关Chap.I 获取一个文件夹下所有文件的文件名的部分内容Part.IV 结构体相关Chap.I 读取结构体Chap.II 取结构体中某一字段的所有值本篇博文记录一些笔者使用 Matlab 时&a…...
Echarts 仪表盘倾斜一定角度显示,非中间对称
第024个点击查看专栏目录大多数的情况下,制作的仪表盘都是中规中矩,横向中间对称,但是生活中的汽车,摩托车等仪表盘确是要倾斜一定角度的,Echarts中我们就模拟一个带有倾斜角度的仪表盘。核心代码见示例源代码 文章目录…...
Vue中如何利用websocket实现实时通讯
首先我们可以先做一个简单的例子来学习一下简单的websocket模拟聊天对话的功能 原理很简单,有点像VUE中的EventBus,用emit和on传来传去 首先我们可以先去自己去用node搭建一个本地服务器 步骤如下 1.新建一个app.js,然后创建pagejson.js文…...
力扣解法汇总1144. 递减元素使数组呈锯齿状
目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给你一个整数数组 nums,每次 操作 会从中选择一个元素并 将该元素的…...
Spring彻头彻尾的讲解,按照Spring框架启动流程,逐步剖析问题,不再是大杂烩!
文章目录1. 定义Spring Bean篇1.1 定义Spring Bean的几种方式1.1.1 XML文件定义Spring Bean1.1.2 JavaConfig定义Spring Bean1.1.3 Component注解定义SpringBean1.2 装配Spring Bean的四种常用方式1.2.1 手动装配 XML文件1.2.2 自动装配 XML文件1.2.3 手动装配 JavaConfig文…...
[2]MyBatis+Spring+SpringMVC+SSM整合一套通关
二、Spring 1、Spring简介 1.1、Spring概述 官网地址:https://spring.io/ Spring 是最受欢迎的企业级 Java 应用程序开发框架,数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。 Spring 框架是一个开源的 Jav…...
Javascript的API基本内容(三)
一、事件流 假设页面里有个div,当触发事件时,会经历两个阶段,分别是捕获阶段、冒泡阶段简单来说:捕获阶段是 从父到子 冒泡阶段是从子到父实际工作都是使用事件冒泡为主 二、页面加载事件 加载外部资源(如图片、外联CS…...
【Python入门第十九天】Python 函数
函数是一种仅在调用时运行的代码块。 可以将数据(称为参数)传递到函数中。 函数可以把数据作为结果返回。 创建函数 在 Python 中,使用 def 关键字定义函数: 实例 def my_function():print("Hello from a function&quo…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
