【JVM】第三篇 JVM对象创建与内存分配机制深度剖析
目录
- 一. JVM对象创建过程详解
- 1. 类加载检查
- 2. 分配内存
- 2.1 如何划分内存?
- 2.2 并发问题
- 3. 初始化
- 4. 设置对象头
- 5. 执行<init>方法
- 二. 对象头和指针压缩详解
- 三. JVM对象内存分配详解
- 四.逃逸分析 & 栈上分配 & 标量替换详解
- 1. 逃逸分析 & 栈上分配
- 2. 标量替换
- 3. 标量与聚合量
- 4. 对象在堆内存中的流转与分配
- 五.对象内存回收机制详解
- ★ 1. 如何判断对象是可回收的?
- ★ 2. 常见的引用类型
- ★ 3. 对象真正被GC回收的两次标记过程详解
- ★ 4. 如何判断一个类是无用的类?
一. JVM对象创建过程详解

1. 类加载检查
当虚拟机遇到一条new指令时,首先会先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化过。如果没有,必须先执行相应的类加载过程。
2. 分配内存
在类检查通过之后,虚拟机会给新生对象分配内存。对象所需要的内存大小在类加载完成之后就可以确定,为对象分配空间的任务等同于把一块确定的内存从JVM堆中划分出来。
2.1 如何划分内存?
指针碰撞(Bump the Pointer): 默认使用; 如果JVM堆中的内存是绝对规整的,所有用过的内存在一边,空闲的内存放在另外一边,中间放一个指针作为分界点的指示器,那所分配内存就是将指针向空闲空间那边挪动一段与对象大小相等的距离

空闲列表(Free List):JVM堆中的内存并不是规整的,已使用的内存和空闲的内存相互交错,此时就无法使用指针碰撞了,JVM就必须维护一个空闲内存的列表,记录堆中哪些位置是可用的,在分配内存时,在列表中分配一块足够大的空间给对象实例,并且更新列表上的记录。

★ 为啥默认使用指针碰撞方式?- 空闲列表中,已使用的空间是
无规则排列的,并且未使用的内存空间的大小是不一致的,当一个对象实例需要存储的时候,就需要先去空闲列表中找一个和实例大小相匹配的内存空间,并且还需要更新空闲列表。 - 空闲列表,无法将内存空间使用率最大化。
- 空闲列表中,已使用的空间是
2.2 并发问题
- 如何产生?
指针碰撞:当给对象A分配内存时,指针位置还未及时修改,此时对象B也使用原来的指针来分配内存空间,俗称抢内存。空闲列表:当给对象A分配内存时,在空闲列表寻找合适对象A的内存空间,如果此时找到一块内存位置,还未及时存入对象A,空闲列表也未做更新,对象B也通过空闲列表找到同一块内存位置,此时就会出现两个对象争抢同一块内存空间的现象。
- 解决办法?
CAS(Compare And Swap):比较与交换,是实现多线程同步的原子指令,将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容更新为给定值。JVM虚拟机采用CAS并且配上失败重试的方式保证更新操作的原子性来对分配内存空间的动作进行同步处理。TLAB(Thread Local Allocation Buffer):线程本地分配缓存区,把内存分配的动作按照线程划分在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存 。
3. 初始化
内存分配完成后,JVM虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头)(如果使用TLAB,此步骤也可以提前至TLAB分配时进行),保证了对象的实例字段在Java代码中可以不赋初始值就可以直接使用,程序能访问到这些字段类型所对应的零值。
4. 设置对象头

★ 初始化零值之后,虚拟机需要对对象进行的必要的设置,例如:这个对象是哪个类的实例,如何才能找到类的元数据信息,对象的哈希码值,对象的GC分代年龄等信息,这些信息存放在对象的对象头Object Header中。
★ 在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
★ HotSpot虚拟机的对象头包括 两部分信息
第一部分用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等。
另外一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
5. 执行方法
即对象按照程序的编码进行初始化,也就是属性赋值(此处赋值,并非赋零值,而是真实的程序编码赋予的值)和执行构造方法 。
二. 对象头和指针压缩详解

Mark word是一种用于对象头部的标记,它记录了对象的元数据信息和运行时状态。
在JVM中,每个对象都有一个对象头部,用于描述对象的元数据信息和运行时状态。其中,mark word记录了对象的锁状态、GC状态以及其他一些标志位信息。它可以被用于多种用途,如实现线程安全、对象的同步和对象的标记-清除等垃圾回收算法。在64位JVM中,mark word占据了8字节的空间,可以存储更多的信息,因此可以提高JVM的性能。Klass pointe: 是指向对象类元数据的指针,在64位JVM中,klass pointer占据了4字节的空间。
每个Java对象都有一个klass pointer,它指向该对象所属的类的元数据。元数据描述了该类的所有属性,方法和其他信息。klass pointer也被用于确定对象的大小和布局,以便在内存中分配对象时可以正确地分配空间。
模拟: 对象大小和指针压缩(代码如下)
- 首先需要在项目的pom文件中依赖jol-core包
<!-- 可以明细jvm中的对象大小 -->
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.9</version>
<相关文章:
【JVM】第三篇 JVM对象创建与内存分配机制深度剖析
目录 一. JVM对象创建过程详解1. 类加载检查2. 分配内存2.1 如何划分内存?2.2 并发问题3. 初始化4. 设置对象头5. 执行<init>方法二. 对象头和指针压缩详解三. JVM对象内存分配详解四.逃逸分析 & 栈上分配 & 标量替换详解1. 逃逸分析 & 栈上分配2. 标量替换…...
【信创】麒麟v10(arm)-mysql8-mongo-redis-oceanbase
Win10/Win11 借助qume模拟器安装arm64麒麟v10 前言 近两年的国产化进程一直在推进,基于arm架构的国产系统也在积极发展,这里记录一下基于麒麟v10arm版安装常见数据库的方案。 麒麟软件介绍: 银河麒麟高级服务器操作系统V10 - 国产操作系统、银河麒麟、中…...
maven settings.xml文件(包含了配置阿里云镜像)
mac 的 settings.xml 我配置的位置是: /Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/conf/settings.xml 然后 local repository 我配置的位置是: /Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/conf/repos…...
分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测
分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测 目录 分类预测 | MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结合支持向量机分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现WOA-FS-SVM鲸鱼算法同步优化特征选择结…...
Redis是否要分库的实践
Redis的分库其实没有带来任何效率上的提升,只是提供了一个命名空间,而这个命名空间可以完全通过key的设计来避开这个问题。 一个优雅的Redis的key的设计如下...
String 进阶
字符串拼接 // 常量与常量的拼接结果放在常量池 // 常量池中不会存在相同的常量 String str1 "a" "b"; System.out.println(str1 "ab");// 拼接时有一个为变量,则结果会放在堆中。 // 变量拼接的原理是 StringBuilder append 最后…...
ESP32设备通信-两个ESP32间UART通信
两个ESP32间UART通信 文章目录 两个ESP32间UART通信1、UART介绍2、软件准备3、硬件准备4、代码实现在本文中,我们将使用 Arduino IDE 的 UART 硬件库在两个 ESP32 板之间执行 UART 或串行通信。 要使用 USB 端口调试和编程 ESP32,需要使用称为通用异步接收器/发送器 (UART) 通…...
LCR 052.递增顺序搜索树
题目来源: leetcode题目,网址:LCR 052. 递增顺序搜索树 - 力扣(LeetCode) 解题思路: 中序遍历时修改指针即可。 解题代码: /*** Definition for a binary tree node.* public class TreeNo…...
Mysql集群技术问答
前提:Mysql集群服务部署到一个群组的所有服务器上,一般20台为一个群组,群组内所有节点数据实时同步,动态自动维护节点。 问:集群空间跟传统空间的最大不同是什么? 答:集群空间有数据同步和宕机检…...
2023版 STM32实战4 滴答定时器精准延时
SysTick简介与特性 -1- SysTick属于系统时钟。 -2- SysTick定时器被捆绑在NVIC中。 -3- SysTick可以产生中断,且中断不可屏蔽。 SysTick的时钟源查看 通过时钟树可以看出滴答的时钟最大为72MHZ/89MHZ 通过中文参考手册也可以得到这个结论 代码编写(已经验证&a…...
ESP32设备驱动-数据持久化到Flash
数据持久化到Flash 文章目录 数据持久化到Flash1、Preferences库介绍2、软件准备3、硬件准备4、代码实现4.1 初始化NVS Flash4.2 读写Key/Value对4.3 保存/读取网络凭据4.4 复位后记住最后的 GPIO 状态在本文中,我们将介绍如何使用 Preferences库将数据存储到 ESP32 的Flash中…...
Swift data范围截取问题
文章目录 一、截取字符串的几种方法1. 截取前几位2. 截取后几位3. subData4. 下标截取 二、subData(in:) 报错 EXC_BREAKPOINT 一、截取字符串的几种方法 1. 截取前几位 mobileID.prefix(32)2. 截取后几位 mobileID.suffix(3)3. subData data.subdata(in: 0..<4)4. 下标…...
PICO首届XR开发者挑战赛正式启动,助推行业迈入“VR+MR”新阶段
9月25日,“PICO 2023首届XR开发者挑战赛”(下文简称“挑战赛”)媒体启动会在北京圆满落幕,官方赛事报名通道已于今日开启。据悉,本次挑战赛是PICO首次针对全球开发者举办的大型挑战赛事,旨在与开发者保持连…...
【计算机网络】应用层协议原理
文章目录 网络应用程序体系结构客户-服务器体系结构P2P体系结构 进程通信客户和服务器进程进程与计算机网络之间的接口进程寻址 可供应用程序使用的运输服务可靠数据传输吞吐量定时安全性 因特网提供的运输服务TCP服务面向连接的服务可靠数据传输服务TCP安全 UDP服务因特网运输…...
buuctf-[WUSTCTF2020]CV Maker
打开环境 随便登录注册一下 进入到了profile.php 其他没有什么页面,只能更换头像上传文件,所以猜测是文件上传漏洞 上传一句话木马看看 <?php eval($_POST[a]);?>回显 搜索一下 添加文件头GIF89a。上传php文件 查看页面源代码,看…...
数据库表操作详解
在数据库管理中,表操作是最基础也最常用的一项功能。不论是临时存储一些数据,还是通过派生表进行复杂的查询,表操作的灵活性和多样性都使其在数据库中发挥着重要的作用。 本文将详细解析数据库中常见的表操作,包括临时表、派生表以及与视图、子查询的比较。我们将使用游戏…...
axios配置代理ip
axios配置代理ip 对于在nodejs中使用axios作为请求库时,有需要配置代理ip的需求(比如爬虫等等) 最离谱的是,在网上搜了一圈,全是关于axios配置proxy跨域的解决办法,没有配置代理ip的方法。 const axios …...
Apache Commons Pool2 池化技术
对象池是一种设计模式,用于管理和重用对象,以提高性能和资源利用率。对象池的概念在许多应用程序中都有广泛应用,特别是在需要频繁创建和销毁对象的情况下,例如数据库连接、线程、HTTP连接等 对象池通过预先创建一组对象并将它们存…...
二叉树的最近公共祖先LCA
系列题目 236. 二叉树的最近公共祖先 1676. 二叉树的最近公共祖先IV 1644. 二叉树的最近公共祖先 II 235. 二叉搜索树的最近公共祖先 1650. 二叉树的最近公共祖先 III class LowestCommonAncestor:"""236. 二叉树的最近公共祖先题目强调p和q一定存在于二叉树中&…...
AWS SAA知识点整理(作成中)
共通 一些信息已经更新了,但参考题的答案还是旧的。 比如: S3的最大读写性能已经提高到 3,500 PUT/COPY/POST/DELETE or 5,500 GET/HEAD requests per second 并且不再要求使用random prefix 题目中有时候会让选择Not violation 不合适的一项ÿ…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
