JVM类加载和垃圾回收(详细)
文章目录
JVM
介绍
JDK/JRE/JVM的关系
JDK:JRE+编译工具
JRE:JVM+基础类库
JVM
内存结构

堆
-
存放对象实例
对象
-
对象头:标记字段和类型指针
-
实例数据
-
对其填充
-
-
字符串常量池:避免字符串的重复创建
-
静态变量
程序计数器
作用:记住下一条jvm指令的执行地址
多线程的情况下,程序计数器记录当前线程的执行位置,当线程切换回来时能够知道运行到那里
tip:唯一一个不会内存溢出的内存区域,随线程的创建而创建,结束而死亡
虚拟机栈
作用:为虚拟机执行java方法服务
栈帧
-
局部变量表:存放编译期可知的各种数据类型和对象引用
-
操作数栈:存放方法执行过程中产生的中间计算结果
-
动态链接:将类常量池中的符号应用转换为直接引用
-
方法返回地址
- 两种返回方式:正常返回和抛出异常
本地方法栈
作用:为虚拟机执行Native方法服务
本地内存
-
元空间(方法区的实现类)
- 运行时常量池:常量池表存放字面量和符号引用,在类加载后存放到方法的运行时常量池中
-
直接内存
类文件
字节码文件
作用:
-
是不同语言和Java虚拟机之间的重要桥梁
-
是Java跨平台的重要原因(字节码不针对特定的机器,java程序无需重新编译就可以在不同操作系统的计算机上运行)
结构

-
魔数:确定这个文件是否为一个能被虚拟机接收的Class文件(4字节)
-
Class 文件版本号
- 次版本号(2字节)
- 主版本号(2字节)
-
常量池:存放字面量和符号引用
-
访问标志:识别一些类或接口层次的访问信息
-
当前类
-
父类
-
接口集合
-
字段表集合:成员变量(实例变量和类变量)
-
方发表集合
-
属性表集合
类加载
类的生命周期

加载
- 通过全类名获取定义此类的二进制字节流
- 将字节流所代表的静态存储结构装换位方法区的运行时数据结构
- 在内存中生成一个代表此类的Class对象,作为方法区中数据的访问入口
类加载器
定义:类加载器是一个加载类的对象;
每一个Java类都有一个引用指向加载它的ClassLoader;
数组类不是通过类加载器创建的(没有对应的二进制字节流),由JVM直接生成。
作用:加载Java类的class文件到JVM中(在内存中生成一个代表此类的Class对象)
加载规则:
-
大部分类在使用时才会被加载
-
一个类只会被加载一次
双亲委派模型
定义:ClassLoader实例会在尝试亲自查找类或资源之前,将查找类或资源的任务委托给父类加载器
tip:除了启动类加载器外,其他类加载器都有自己的父类加载器
各种类加载器之间的层次关系:
-
启动类加载器:加载JDK内部的核心类库%JAVA_HOME%/lib,由C++实现
-
扩展类加载器:加载%JRE_HOME%/lib/ext下的jar包和类
-
应用程序类加载器:加载应用classpath下的所有jar包和类
-
自定义类加载器:需要继承ClassLoader抽象类
-
findClass()根据二进制名称查找类
-
loadClass()加载指定二进制名称的类,实现了双亲委派机制
-
执行流程:
-
判断是否被加载过
-
将加载类的请求委托给父类加载器去完成(调用loadClass()方法)
-
所有的父类加载器无法加载这个类时,子加载器会尝试自己去加载(调用findClass()方法)
-
子类加载器也无法加载这个类,抛出ClassNotFoundException异常
tip:判断两个Java类是否相同:
1.类的全类名相同
2.类的类加载器相同
好处:
-
避免了类的重复加载
-
保证Java核心API不被篡改
打破双亲委派模型的方法:自定义加载器,继承ClassLoader,重写loadClass()
链接
验证:保证Class文件的字节流中包含的信息符合全部约束要求,不会危害虚拟机自身安全
-
文件格式验证
-
元数据验证(字节码语义检查)
-
字节码验证(程序语义检查)
-
符号引用验证(类的正确性检查)
准备:为类变量分配内存并设置类变量初始值(在方法区分配)
tip:jdk7之后字符串常量池、静态变量等移动到了堆中
解析:将常量池中的符号引用转化为直接引用(虚拟栈中的动态链接)
初始化
执行初始化方法clinit()的条件:
-
new创建实例
-
getstatic访问类的静态变量
-
putstatic给静态变量复制
-
invokestatic调用类的静态方法
-
需要初始化类的父类
-
主类
类卸载
满足条件:
-
给类的素有实例对象都已经被GC
-
该类没有在其他地方被引用
-
该类的类加载器的实例被GC
垃圾回收
堆空间的基本结构
堆是垃圾回收的主要区域,也称GC堆
结构:
- 新生代
- 老生代
- 永久代(元空间)

内存分配和回收原则
内存分配
-
对象优先在Eden区分配
-
大对象直接进入老年代
- 大对象指需要大量连续内存空间的对象(比如:字符串、数组)
- 避免将大对象放入新生代,减少新生代的垃圾回收频率和成本
-
长期存活的对象进入老年代
- 当Survivor空间的对象达到晋升年龄阈值(默认15)时,会被放入到老年代中
主要进行gc的区域
-
部分收集Partial GC
-
新生代收集Minor GC / Young GC:只对新生代进行垃圾收集
-
老年代收集Major GC / Old GC:只对老年代进行垃圾收集
-
混合收集Mixed GC:对整个新生代和部分老年代进行垃圾收集
-
-
整堆收集Full GC
空间分配担保:将新生代对象转移到老年代
死亡对象判断方法
-
引用计数法
定义:当引用它时,+1;引用失效时,-1;计数器为0时,对象就不可能再被使用了
缺点:无法解决对象之间循环引用的问题
-
可达性分析算法
定义:判断对象到GC Roots是否可达(可达:存在引用链)
可以作为GC Roots:
-
方法区中静态变量、常量引用的对象
-
虚拟栈中引用的对象
-
本地方法栈中引用的对象
-
所有被同步锁持有的对象
-
JNI(Java Native Interface)引用的对象
-
引用类型
强引用:一定不会被回收
软引用:内存空间不足的时候,回收
弱引用:扫描到就会回收
虚引用:用来跟踪对象被垃圾回收的过程,必须配合引用队列使用
垃圾收集算法
-
标记-清除算法:标记不需要回收的对象(可达对象),清除没有标记的对象
缺点
-
效率问题:标记和清除过程效率不高
-
空间问题:回收后会产生大量不连续的内存碎片
-
-
复制算法:将内存划分为大小相同的两块,把存活的对象复制到另一块内存上,再把使用的空间全部清除
缺点
-
可用内存变小
-
不适合老年代:如果存活对象比较大,复制性能会变差
-
-
标记-整理算法:先标记不需要回收的对象,然后让存活对象移动到一段,最后清除到端边界以外的内存
缺点
- 效率不高,适合老年代这种垃圾回收频率不高的场景
-
分代收集算法:根据对象存活周期不同划分为新生代和老年代,不同年代选择合适的垃圾收集算法
新生代:复制算法,大量对象死亡,只需要复制少量对象
老年代:标记-清除或标记-整理,对象存活率高,需要清除的较少
垃圾收集器
-
Serial收集器:使用一条线程进行垃圾收集工作时,暂停其他所有工作线程
-
Serial Old收集器:Serial收集器的老年代版本
-
ParNew收集器:Serial收集器的多线程版本
-
Parallel Scavenge收集器:提高CPU利用率
-
Parallel Old收集器:Parallel Scavenge收集器的老年代版本
-
CMS收集器:获得最短回收停顿时间的收集器,提高用户体验;真正意义上的并发收集器,垃圾收集线程和用户线程同时工作
四个步骤
-
初始标记:短暂停顿,标记可达对象
-
并发标记:开启GC和用户线程,标记可达对象,但不包含所有可达对象,因为用户线程会导致标记变动
-
重新标记:短暂停顿,修正并发标记期间的对象标记记录
-
并发清除:开启GC和用户线程,对未标记区域进行清除
优点
-
并发收集
-
低停顿
缺点
-
对CPU资源敏感
-
无法处理浮动垃圾
-
标记-清除算法,会产生大量空闲碎片
-
-
G1收集器:面向服务器的垃圾收集器,针对于配备了多颗处理器的机器
四个步骤
-
初始标记:短暂停顿,标记可达对象
-
并发标记:开启GC和用户线程,标记可达对象,但不包含所有可达对象,因为用户线程会导致标记变动
-
最终标记:短暂停顿,修正并发标记期间的对象标记记录
-
筛选回收:选择回收价值高的区域,复制存活对象到新区域,清楚旧区域
-
-
ZGC收集器
相关文章:
JVM类加载和垃圾回收(详细)
文章目录 JVM介绍JDK/JRE/JVM的关系 内存结构堆程序计数器虚拟机栈本地方法栈本地内存 类文件字节码文件结构 类加载类的生命周期加载类加载器双亲委派模型 链接初始化类卸载 垃圾回收堆空间的基本结构内存分配和回收原则死亡对象判断方法垃圾收集算法垃圾收集器 JVM 介绍 JD…...
秘密信息嵌入到RGB通道的方式:分段嵌or完整嵌入各通道
目录 1. 将秘密信息分为三部分的理由 (1)均匀分布负载 (2)提高鲁棒性 (3)容量分配 2. 不将秘密信息分为三部分的情况 (1)嵌入容量 (2)视觉质量 &#…...
基于Flask的影视剧热度数据可视化分析系统的设计与实现
【FLask】基于Flask的影视剧热度数据可视化分析系统的设计与实现(完整系统源码开发笔记详细部署教程)✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网技术的飞速发展,影视剧行业的数据量呈爆炸性增长&#x…...
Docker Desktop如何恢复出厂设置
在测试dify、ragfow等几个模型过程中,各种拉镜像建容器,导致错误提示“AssertionError(Can t access Redis. Please check the Redis status.)”,两个模型都无法使用,如何清空重建?请参照下面操作: 1、Win…...
Go语言协程Goroutine高级用法(一)
什么协程 在Go语言中,协程就是一种轻量的线程,是并发编程的单元,由Go来管理,所以在GO层面的协程会更加的轻量、高效、开销更小,并且更容易实现并发编程。 轻量级线程 Go语言中协程(线程)与传…...
Android Studio:键值对存储sharedPreferences
一、了解 SharedPreferences SharedPreferences是Android的一个轻量级存储工具,它采用的存储结构是Key-Value的键值对方式,类似于Java的Properties,二者都是把Key-Value的键值对保存在配置文件中。不同的是,Properties的文件内容形…...
网络安全-攻击路径
以下是互联网场景下常见的攻击路径分类及详细说明,以分层结构呈现: 一、网络层攻击路径 DDoS攻击 原理:通过僵尸网络发起海量请求淹没目标服务器示例:SYN Flood攻击、HTTP洪泛攻击影响:服务不可用,带宽资源…...
记录阿里云CDN配置
网站接入CDN全流程,共4步!-阿里云开发者社区 1、开通阿里云CDN服务 2、添加加速域名 3、验证域名归属权 4、域名添加CDN生成的CNAME解析 按照官网描述增加。细节点: 1. 域名和泛域名区别 2.开启https,要用nginx的证书,和项…...
国自然专项项目申请:AI赋能的急性心肌梗死预警研究|基金申请·25-02-14
小罗碎碎念 急性心肌梗死严重威胁生命健康,因其起病隐匿、发病机制复杂,早期预警困难。现在,转机来了!国自然“AI赋能的急性心肌梗死预警研究”专项项目2025年度指南重磅发布。 该项目致力于攻克难题,通过多学科交叉…...
【鸿蒙开发】第二十八章 应用状态的讲解、状态持久化、网络管理、应用数据持久化、文件上传下载
目录 1 应用状态 1.1 LocalStorage:页面级UI状态存储 1.1.1 两个页面共享一个对象 1.1.2 页面间共享 1.1.3 应用逻辑中使用 1.2 AppStorage:应用全局的UI状态存储 1.2.1 概述 1.2.2 基本用法 1.2.3 经常使用的方法 1.3 PersistentStorage&#x…...
学习threejs,使用HemisphereLight半球光
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.HemisphereLight 二、…...
天童美语:观察你的生活
在孩子的认知里,世界宛如一片充满神秘色彩的未知之境,有着无尽的奥秘等待他们去探索。家长们,引导孩子用心观察世界,领略其中的美妙,这对孩子的成长进程有着极为关键的作用。贵阳天童教育相信:观察生活&…...
数仓:核心概念,数仓系统(ETL,数仓分层,数仓建模),数仓建模方法(星型模型,雪花模型,星座模型)和步骤
数仓建模的核心概念 事实表(Fact Table): 存储业务过程的度量值(如销售额、订单数量等)。 通常包含外键,用于关联维度表。 维度表(Dimension Table): 存储描述性信息&…...
python 基础知识100问
目录 1 Python中函数的输入参数类型: 2 python 第一个方法参数 selt cls 3 类和面向对象 4 Python 中__init__.py 作用 5 python 元类与装饰器 元类与装饰器https://blog.csdn.net/qq_52213943/article/details/145175689?spm1001.2014.3001.5506 6 设…...
Linux入侵检查流程
1. 初步信息收集 1.1 系统信息 • 目的:了解当前系统的基本情况,包括操作系统版本、内核版本等。 • 命令: # 查看操作系统发行版信息 cat /etc/os-release # 查看内核版本 uname -r 1.2 网络信息 • 目的:查看网络连接状态、…...
pg_sql关于时间的函数
1、时间戳和日期之间的相互转换 时间戳转日期(时间戳为数值类型,若为字符型需进行转换) # 保留到秒:2025-10-02 04:46:40 (字符型转换数值型) select to_timestamp(1759351600::bigint)# 保留到日&#x…...
如何使用 DeepSeek R1 构建开源 ChatGPT Operator 替代方案
开源大型语言模型(LLMs)的兴起使得创建 AI 驱动的工具比以往任何时候都更容易,这些工具可以与 OpenAI 的 ChatGPT Operator 等专有解决方案相媲美。在这些开源模型中,DeepSeek R1 以其强大的推理能力、自由的可访问性和适应性而脱…...
【教程】MySQL数据库学习笔记(七)——多表操作(持续更新)
写在前面: 如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持! 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 第四章 《数据操…...
Word 公式转 CSDN 插件 发布
经过几个月的苦修,这款插件终于面世了。 从Word复制公式到CSDN粘贴,总是出现公式中的文字被单独提出来,而公式作为一个图片被粘贴的情况。公式多了的时候还会导致CSDN禁止进一步的上传公式。 经过对CSDN公式的研究,发现在粘贴公…...
【设计模式】 建造者模式和原型模式
建造者模式(Builder Pattern) 概述 建造者模式是一种创建型设计模式,它允许逐步构建复杂对象。通过将构造过程与表示分离,使得同样的构建过程可以创建不同的表示。这种模式非常适合用于创建那些具有很多属性的对象,尤…...
win7误删注册表文件夹导致exe无法执行
今天在装某个软件的时候报错 “不是有效的Win32应用程序”,找一篇文章于是按文章删除了注册表上的好多文件,之后就发现所有的exe文件都打不开了,更糟糕的是中间还弹出来一个“是否将IE设置为所有程度的默认执行程序”,没思考就点击…...
【ESP32接入国产大模型之Deepseek】
【ESP32接入国产大模型之Deepseek】 1. Deepseek大模型1.1 了解Deepseek api1.2 Http接口鉴权1.3. 接口参数说明1.3.1 请求体(request)参数1.3.2 模型推理 2. 先决条件2.1 环境配置2.2 所需零件 3. 核心代码3.1 源码分享3.2 源码解析3.3 连续对话修改后的代码代码说明示例输出注…...
C语言蓝桥杯1003: [编程入门]密码破译
要将"China"译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母. 例如,字母"A"后面第4个字母是"E"."E"代替"A"。因此,"China"应译…...
New Game--(单调队列)
I - New Game 有一种新的游戏,Monocarp 想要玩。这个游戏使用一副包含 n 张牌的牌堆,其中第 i 张牌上写有一个整数 a_i。 在游戏开始时,Monocarp 可以在第一轮选择牌堆中的任意一张牌。在接下来的每一轮中,Monocarp 可以选择一张…...
什么是偏光环形光源
偏光环形光源是一种特殊的光源,常用于机器视觉、光学检测和工业自动化等领域。它结合了环形光源和偏光技术,能够有效减少反射、增强对比度,特别适用于检测高反光或表面复杂的物体。 主要特点: 环形设计:光线均匀照射物…...
SolidWorks速成教程P3-3【零件 | 第三节】——草图绘制面实线与构造线的区别
经过了前面的特征学习后,是不是感觉对 SolidWorks越来越熟悉了?不过发现, SolidWorks速成这套教程,对于一些基础问题,还是需要解释得更详细一些,所以在这节再补充一下草图绘制面&实线与构造线的区别。 目录 1.草图绘制面 2.实线与构造线的区别 1.草图绘制面 之前…...
win10中mstsc远程Centos-Stream 9图形化界面
文章目录 1 前置状态2 安装配置XRDP3 关闭SELinux3.1 查看selinux状态3.2 关闭selinux 4 启动XRDP5 Win10远程连接测试 1 前置状态 已安装CentOS9桌面版;Windows10。 2 安装配置XRDP sudo yum install epel-release sudo yum install xrdp sudo yum install tige…...
中国AI“拥抱开源”给世界的启示——Anko
事实证明,中国AI企业“拥抱开源”,不仅为自身发展开拓了新路径,也带动AI企业跨国合作的需求,并推动全球AI生态向“开源普惠”转型。Anko通过免费开放部分模型功能,将AI时代的数字红利公平地派发到每一位网民手中&#…...
DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件
1 DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强,如果不能在企业的自有业务上产生助益,那基本也是一无是处。将企业的自有业务上传到线上训练,那是脑子进水的做法ÿ…...
Jenkins 配置 Git Parameter 四
Jenkins 配置 Git Parameter 四 一、开启 项目参数设置 勾选 This project is parameterised 二、添加 Git Parameter 如果此处不显示 Git Parameter 说明 Jenkins 还没有安装 Git Parameter plugin 插件,请先安装插件 Jenkins 安装插件 三、设置基本参数 点击…...
