五、HotSpot细节实现
一、并发标记与三色标记
问题:三色标记到底发生在什么阶段,替代了什么。并发标记
1、并发标记( Concurrent Marking)
从 GC Root 开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗时较长,但可与用户程序并发执行。当对象图扫描完成以后 ,并发标记时有引用变动的对象 ,这些对象会漏标。
CMS和G1的并发标记阶段使用的标记清除扫秒算法占用了太长中断时间,所以用三色标记替换。
2、三色标记的概念(多线程)
在三色标记之前有一个算法叫Mark-And-Sweep(标记清除)。这个算法会给每一个对象设置一个标志位来记录对象是否被使用。最开始标识位都是0,如果发现对象可达就会设置为1,一步步下去就会呈现一个类似树状的结果。等标记的步骤完成后,会将被标记的对象统一清理,再次把所有的标记位置设置成0方便下次清理。
标记清除最大的问题是GC执行期间需要把整个程序完全暂停,不能异步进行GC操作。因为不同阶段标记清除法的标志位0和1有不同的含义,那么新增的对象无论标记成什么都有可能意外删除。对实时性要求高的系统来说,这种需要长时间挂起的标记清除算法是不可接受的。所以就需要一个算法来解决GC运行时程序长时间挂起的问题,那就是三色标记。
三色标记最大的好处就是异步,从而可以以中断时间极少的代价或者完全没有中断来进行整个GC
三色标记把对象用三种颜色标记
- 黑色:根对象,或者这个对象及他的子对象都已经被扫描了
- 灰色:本身已经扫描了,子对象还没扫描
- 白色:未被扫描的对象,如果扫描完所有的对象之后,最终白色的为不可达对象,既为垃圾
3、三色标记的问题
GC并发情况下会有漏标的问题
第一步:线程1完成所有的标记,线程2还处于半完成状态
第二步:引用发成变化,B指向C变成A指向C
第三步:线程1、2都完成所有的标记,C对象是白色,被错误的回收
4、三色标记并发情况下漏标记解决方案(单线程,最终标记)
(1)cms的解决方案 incremental update 增量更新算法
CMS的三色标记发生并发标记和重新标记阶段
当一个白色对象被一个黑色对象引用,将黑色对象重新标记为灰色,让垃圾回收器重新扫描。增量更新,关注的是引用新增。
(2)G1中的解决方案 STAB (snapshot-at-the-beginning) 快照处理算法
刚开始做一个快照,当B指向C的引用消失的时候,就把这个引用推到GC的堆栈,保证C还能被GC扫描到,最重要的是要把这个引用推到GC的堆栈,是灰色对象B指向白色C的引用,如果一旦某一个引用消失掉了,会把它放到栈(GC方法运行时数据也是来自栈中),其实还是能找到它的,下回直接扫描他就行了,那样白色就不会漏标。再次做一个快照,然后两个快照进行对比,发现C不是垃圾,那就要对C单独再做一次处理。
对应 G1 的垃圾回收过程中的:最终标记
对用户线程做另外一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录(漏标对象)
(3)incremental update与STAB对比
为什么CMS不用快照,为什么G1不用增量
incremental Update算法关注引用的增加。(A-C的引用),如果增加了就变灰色,需要重新扫描
SATB算法是关注引用的删除(B->C的引用)
G1 如果使用 Incremental Update 算法,因为变成灰色的成员还要重新扫,重新再来一遍,效率太低了。
所以 G1 在处理并发标记的过程比 CMS 效率要高,但是占内存高,这个主要是解决漏标的算法决定的。
三、安全点与安全区域
1、安全点(不会发生引用的变化的代码)
用户线程暂停,GC 线程要开始工作,但是要确保用户线程暂停的这行字节码指令是不会导致引用关系的变化。
所以 JVM 会在字节码指令中,选一些指令,作为“安全点”,比如方法调用、循环跳转、异常跳转等,一般是这些指令才会产生安全点。
为什么它叫安全点,GC 时要暂停业务线程,并不是抢占式中断(立马把业务线程中断)而是主动式中断。主动式中断是设置一个标志,这个标志是中断标志,各业务线程在运行过程中会不停的主动去轮询这个标志,一旦发现中断标志为 True,就会在自己最近的“安全点”上主动中断挂起。
业务线程停止---安全点--->垃圾回收线程开始
业务线程主动式中断,GC开始,STW业务线程, 业务线程轮训标志S(0 OR 1),即GC开始标志,主动去中断线程,跑到最近的安全点挂起。
2、安全区域
为什么需要安全区域?
要是业务线程都不执行(业务线程处于 Sleep 或者是 Blocked 状态),那么程序就没办法进入安全点,对于这种情况,就必须引入安全区域。
安全区域是指能够确保在某一段代码片段之中, 引用关系不会发生变化,因此,在这个区域中任意地方开始垃圾收集都是安全的。我们也可以把安全区城看作被扩展拉伸了的安全点。
当用户线程执行到安全区域里面的代码时,首先会标识自己已经进入了安全区域,这段时间里 JVM 要发起 GC 就不必去管这个线程了。
当线程要离开安全区域时,它要判断 JVM 是否已经完成了GC阶段(根节点枚举,或者其他 GC 中需要暂停用户线程的阶段)
1、如果完成了,那线程就当作没事发生过,继续执行。
2、否则它就必须一直等待, 直到收到可以离开安全区域的信号为止。
四、低延迟的垃圾回收器
1、垃圾回收器的三项指标
传统的垃圾回收器一般情况下内存占用、吞吐量、延迟只能同时满足两个。但是现在的发展,延迟这项的目标越来越重要。所以就有低延迟的垃圾回收器。
2、Eplison(了解即可)
这个垃圾回收器不能进行垃圾回收,是一个“不干活”的垃圾回收器,由 RedHat 推出,它还要负责堆的管理与布局、对象的分配、与解释器的协作、与编译器的协作、与监控子系统协作等职责,主要用于需要剥离垃圾收集器影响的性能测试和压力测试。
3、ZGC(了解即可)
有类似于 G1 的 Region,但是没有分代。
标志性的设计是染色指针 ColoredPointers(这个概念了解即可),染色指针有 4TB 的内存限制,但是效率极高,它是一种将少量额外的信息存储在指针上的技术。
它可以做到几乎整个收集过程全程可并发,短暂的 STW 也只与 GC Roots 大小相关而与堆空间内存大小无关,因此可以实现任何堆空间 STW 的时间小于十毫秒的目标。
JDK11 –ZGC(暂停时间不超过 10 毫秒,且不会随着堆的增加而增加,TB 级别的堆回收)):
有色指针、加载屏障。JDK12 支持并发类卸载,进一步缩短暂停时间 JDK13(计划于 2019 年 9 月)将最大堆大小从 4TB 增加到 16TB
4、Shenandoah(了解即可)
第一款非 Oracle 公司开发的垃圾回收器,有类似于 G1 的 Region,但是没有分代。也用到了染色指针 ColoredPointers。效率没有 ZGC 高,大概几十毫秒的目标。
五、GC 参数和GC 日志详解
1、GC 常用参数
-Xmn -Xms -Xmx –Xss 年轻代 最小堆 最大堆 栈空间
-XX:+UseTLAB 使用 TLAB,默认打开
-XX:+PrintTLAB 打印 TLAB 的使用情况
-XX:TLABSize 设置 TLAB 大小
-XX:+DisableExplicitGC 启用用于禁用对的调用处理的选项 System.gc()
-XX:+PrintGC 查看 GC 基本信息
-XX:+PrintGCDetails 查看 GC 详细信息
-XX:+PrintHeapAtGC 每次一次 GC 后,都打印堆信息
-XX:+PrintGCTimeStamps 启用在每个 GC 上打印时间戳的功能
-XX:+PrintGCApplicationConcurrentTime 打印应用程序时间(低)
-XX:+PrintGCApplicationStoppedTime 打印暂停时长(低)
-XX:+PrintReferenceGC 记录回收了多少种不同引用类型的引用(重要性低)
-verbose:class 类加载详细过程
-XX:+PrintVMOptions 可在程序运行时,打印虚拟机接受到的命令行显示参数
-XX:+PrintFlagsFinal -XX:+PrintFlagsInitial 打印所有的 JVM 参数、查看所有 JVM 参数启动的初始值(必须会用)
-XX:MaxTenuringThreshold 升代年龄,最大值 15, 并行(吞吐量)收集器的默认值为 15,而 CMS 收集器的默认值为 6。
2、Parallel 常用参数
-XX:SurvivorRatio 设置伊甸园空间大小与幸存者空间大小之间的比率。默认情况下,此选项设置为 8
-XX:PreTenureSizeThreshold 大对象到底多大,大于这个值的参数直接在老年代分配
-XX:MaxTenuringThreshold 升代年龄,最大值 15, 并行(吞吐量)收集器的默认值为 15,而 CMS 收集器的默认值为 6。
-XX:+ParallelGCThreads 并行收集器的线程数,同样适用于 CMS,一般设为和 CPU 核数相同
-XX:+UseAdaptiveSizePolicy 自动选择各区大小比例
3、CMS 常用参数
-XX:+UseConcMarkSweepGC 启用 CMS 垃圾回收器
-XX:+ParallelGCThreads 并行收集器的线程数,同样适用于CMS,一般设为和 CPU 核数相同
-XX:CMSInitiatingOccupancyFraction 使用多少比例的老年代后开始 CMS 收集,默认是 68%(近似值),如果频繁发生 SerialOld 卡顿,应该调小,(频繁 CMS 回收)
-XX:+UseCMSCompactAtFullCollection 在 FGC 时进行压缩
-XX:CMSFullGCsBeforeCompaction 多少次 FGC 之后进行压缩
-XX:+CMSClassUnloadingEnabled 使用并发标记扫描(CMS)垃圾收集器时,启用类卸载。默认情况下启用此选项。
-XX:CMSInitiatingPermOccupancyFraction 达到什么比例时进行 Perm 回收,JDK 8 中不推荐使用此选项,不能替代。
-XX:GCTimeRatio 设置 GC 时间占用程序运行时间的百分比(不推荐使用)
-XX:MaxGCPauseMillis 停顿时间,是一个建议时间,GC 会尝试用各种手段达到这个时间,比如减小年轻代
4、G1 常用参数
-XX:+UseG1GC 启用 CMS 垃圾收集器
-XX:MaxGCPauseMillis 设置最大 GC 暂停时间的目标(以毫秒为单位)。这是一个软目标,并且 JVM 将尽最大的努力(G1 会尝试调整 Young 区的块数来)来实
现它。默认情况下,没有最大暂停时间值。
-XX:GCPauseIntervalMillis GC 的间隔时间
-XX:+G1HeapRegionSize 分区大小,建议逐渐增大该值,1 2 4 8 16 32。随着 size 增加,垃圾的存活时间更长,GC 间隔更长,但每次 GC 的时间也会更长
-XX:G1NewSizePercent 新生代最小比例,默认为 5%
-XX:G1MaxNewSizePercent 新生代最大比例,默认为 60%
-XX:GCTimeRatioGC 时间建议比例,G1 会根据这个值调整堆空间
-XX:ConcGCThreads 线程数量
-XX:InitiatingHeapOccupancyPercent 启动 G1 的堆空间占用比例,根据整个堆的占用而触发并发 GC 周期
相关文章:

五、HotSpot细节实现
一、并发标记与三色标记 问题:三色标记到底发生在什么阶段,替代了什么。并发标记 1、并发标记( Concurrent Marking) 从 GC Root 开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,这阶段耗…...

DRBD分布式存储实验
DRBD DRBD的全称为:Distributed Replicated Block Device (DRBD) 分布式块设备复制 与心跳连接结合使用,构建高可用性(HA)的集群。 实现方式是通过网络来镜像(mirror)整个设备。它允许用户在远程机器上建立一个本地块设备的实时镜像。DRBD负责接收数据…...
go的结构体作为返回值
结构体有两种方式作为返回值 结构体结构体指针 代码 package mainimport ("fmt" )type SS struct {Name stringAge int }func getInfo() (*SS) {var ac SS{}ac.Age 1return &ac }func getInfo1() (aa *SS) {aa.Age 1return }func getInfo2() (SS) {var ac…...
uniapp的subnvue苹果适配(ios)谷歌地图问题
谷歌地图,google地图,调整宽度。这个适配花了点时间,苹果IOS宽度一直无效失灵,赶紧记录分享,很坑。可能所有的ios的subnvue适配都这样。看了网上很多方法无效,最终找到试出答案。 pages.json的配置宽度无效…...

项目实战之RabbitMQ重试机制进行消息补偿通知
🧑💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 文章目录 🌟架构图&#x…...
MySQL之数据库的创建指令
创建数据库 #创建数据库指令: CREATE DATABASE hsp_db1 #创建名字为关键字的数据库,为规避关键字,可以使用反引号 CREATE DATABASE CREATE#删除数据库指令: DROP DATABASE hsp_db1 DROP DATABASE CREATE如果不指定在这里插入代码片…...
[网络安全]批处理(脚本)编写
Windows DOS命令Linux 一.作用: 自上而下成批次处理每一条命令,直到执行到最后一条 二.如何创建批处理: 扩展名:.bat创建办法:新建一个记事本,把扩展名改为 .bat 三.编辑方法: 右击 -编辑 1).一行一个命令 四.批处理命令: pause 暂停 (及时后面有命令,也不执行)echo …...

事件驱动架构 vs. RESTful架构:通信模式对比与选择
1. 通信风格 事件驱动架构(EDA) 是一种异步通信风格,组件之间通过产生和消费事件进行通信。 事件是表示系统中重大变化或事件的消息,并分发给感兴趣的组件。这种通信模型允许系统的不同部分之间进行解耦和动态交互。 组件充当事件…...
代码随想录算法训练营第五十二天| 300 最长递增子序列 674 最长连续递增子序列 718 最长重复子数组
目录 300 最长递增子序列 674 最长连续递增子序列 718 最长重复子数组 300 最长递增子序列 class Solution { public:int lengthOfLIS(vector<int>& nums) {vector<int>dp(nums.size(),1);//以i结尾的最长递增子序列的长度for(int i 0;i < nums.size()…...

leetcode 101.对称二叉树
学习这部分还是要多画图,多思考 101.对称二叉树 题目 给你一个二叉树的根节点 root , 检查它是否轴对称。 题目链接 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 文字 和 画图 分析 明确结束条件和继续递归条件 判断是否对称…...

【本人新书】《OpenCV应用开发:入门、进阶与工程化实践》
写作初心 OpenCV作为开源的计算机视觉框架已经有超过20年的发展历程,OpenCV4是OpenCV目前为止最重要的里程碑版本。OpenCV4不仅包含了传统图像处理、图像分析、特征提取等模块的各种主流算法算子,还包含了深度学习模型部署与加速支持模块,兼…...
【Linux系统编程】进度条的编写
目录 一,进度条的必备知识 1,缓冲区的粗略介绍 2,回车与换行 二,进度条的初步制作 1,进度条的初步矿建 2,进度条的版本一 3,进度条的版本二 一,进度条的必备知识 1ÿ…...

互斥锁的原理
互斥锁(Mutex,全称Mutual Exclusion)是一种同步机制,用于确保在任意时刻,只有一个线程可以访问共享资源,从而防止数据竞争和不一致性。互斥锁的基本思想是在进入临界区之前,先获取锁;…...

Win10的SVN Adapter V1.0 中黄色感叹号 -- 解决
大部分都问题都可以通过: 关闭 SVN Adapter V1.0 在下载最新的 SVNDrv.sys替换 C:\Windows\System32\drivers 中的同名文件启动 SVN Adapter V1.0 就能成功 但是部分人的电脑 SVN Adapter V1.0 是有感叹号的,说明注册表有问题 先用 CCleaner 修复注册表…...

ubuntu20 安装docker
一.官网安装文档 (基本按官方文档安装) Install Docker Engine on Ubuntu | Docker Docs 二.安装步骤 1.docker 需要64位操作系统、linux内核要在3.1以上 #uname -r 2.卸载可能存在的旧版本 #sudo apt-get remove docker docker-engine docker-ce …...

HarmonyOS开发工具DevEco Studio的下载和安装
一、DevEco Studio概述 一、下载安装鸿蒙应用开发工具DevEco Studio 开发鸿蒙应用可以从鸿蒙系统上运行第一个程序Hello World开始。 为了得到这个Hello World,你需要得到这个Hello World的源代码,源代码是用人比较容易看得懂的计算机编程语言规范写的…...
SHELL21 格式化输出
awk BEGIN{FS""}{for(i1;i<NF;i){if((NF-i)%30&&i!NF) printf $i",";else printf $i};printf "\n"} nowcoder.txt这个 AWK 命令的目的是对文本文件 nowcoder.txt 中的每一行进行处理,将每三个字符插入一个逗号,…...

披荆斩棘的「矿区无人驾驶」,能否真正打开千亿级市场?
随着2022年备受瞩目的台泥句容矿无人驾驶运输项目硬核落地,以及相关科技公司开放该矿24小时无人矿卡生产运营直播以证明其项目并非在演示,2023年全国开启了大规模矿区无人驾驶商业化落地,堪称矿区无人驾驶元年。虽然我国矿区无人驾驶市场渗透…...

智能优化算法应用:基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.灰狼算法4.实验参数设定5.算法结果6.参考文献7.MA…...

论文阅读三——端到端的帧到凝视估计
论文阅读三——端到端的帧到凝视估计 主要内容研究问题文章的解题思路文章的主要结构 论文实验关于端到端凝视估计的数据集3种基线模型与EFE模型的对比在三个数据集中与SOTA进行比较 问题分析重要架构U-Net 基础知识 主要内容 文章从端到端的方法出发,提出了根据he…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...