【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 Heade
r中。
★ 在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 不合适的一项ÿ…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...