当前位置: 首页 > news >正文

jvm三色标记

好的,咱们把专业概念和生活例子结合起来,一步一步说清楚三色标记法:

一、核心概念:用“颜色”给对象贴“状态标签”

就像给家里的物品贴标签,每种颜色代表它在“垃圾回收(大扫除)”中的状态:

  1. 白色(White)
    • 专业定义:初始状态,所有对象默认是白色,代表“未被回收器访问,且暂时不确定是否有用”。回收结束后仍为白色的,就是垃圾,会被清理。
    • 生活例子:你刚进房间,地上的旧杂志、空饮料瓶都先贴“白色”——你还没检查它们,不知道该不该留。
  1. 灰色(Gray)
    • 专业定义:已被回收器访问,但它引用的其他对象还没处理完(相当于“待办清单”)。
    • 生活例子:你手里的书包肯定有用(不能扔),但书包里的东西还没掏出来看,所以给书包贴“灰色”——提醒自己:这东西得接着查里面的东西。
  1. 黑色(Black)
    • 专业定义:已被回收器访问,且它所有引用的对象都处理完了,代表“确定有用,无需再管”。
    • 生活例子:你把书包里的课本、笔盒都检查完了,这时给书包贴“黑色”——表示“书包有用,而且里面的东西也都查过了,不用再碰它了”。

二、工作流程:就像“从确定有用的东西开始,一步步排查所有该留的物品”

1. 初始阶段:先找到“绝对有用的东西”(根对象)
  • 专业定义:根对象是程序中明确活跃的引用(如栈里的变量、静态变量),它们一定有用,是标记的起点。初始时所有对象都是白色,只有根对象被标为灰色。
  • 生活例子:你进房间后,先找出“肯定不能扔”的东西——比如你正拿着的手机、身上穿的外套(这些是“根对象”),给它们贴“灰色”(因为要查它们关联的东西,比如手机壳、外套口袋里的钥匙)。
2. 标记阶段:从灰色开始,一步步“查关联、更新标签”
  • 专业定义:从灰色对象出发,遍历它引用的所有对象:
    • 把一个灰色对象标为黑色(确认它本身有用);
    • 扫描它引用的对象:如果是白色,就标为灰色(加入待查队列);如果已经是灰/黑色,就跳过(避免重复查)。
    • 重复到灰色对象为空(所有有用的都被标记)。
  • 生活例子
    • 拿灰色的手机,贴成黑色(确认手机有用),然后看它的手机壳(白色→贴灰色);
    • 拿灰色的手机壳,贴成黑色,发现它挂着一个挂饰(白色→贴灰色);
    • 拿灰色的挂饰,贴成黑色,发现它没别的关联了;
    • 直到手里没有灰色标签的东西了(所有和“根对象”有关的有用物品都查完了)。
3. 回收阶段:清掉剩下的“白色垃圾”
  • 专业定义:标记结束后,白色对象都是“无法通过根对象访问的垃圾”,通过“清除”或“整理”释放内存。
  • 生活例子:最后剩下的白色标签物品(旧杂志、空饮料瓶),都是“和有用的东西没关系”的垃圾,直接扔进垃圾桶。

咱们结合“打扫房间”的生活场景,同时对应专业逻辑,来讲清楚漏标问题的原因和解决方案:

一、漏标问题:为什么会误删有用的东西?

专业本质:并发回收时,用户线程修改对象引用,导致本应被保留的活跃对象未被标记,最终被误判为垃圾。


生活例子:清洁工(回收器)和你(用户线程)同时在房间里活动,你突然挪动了一个有用的东西,清洁工没察觉,最后把它当垃圾扔了。

漏标的两个必要条件(缺一个都不会发生):
  1. “已处理完的对象”失去了对某个对象的引用
    • 专业:黑色对象(已扫描完的活跃对象)原本引用着一个白色对象(未扫描),但用户线程突然断开了这个引用。
    • 生活:清洁工已经查完你的书包(贴黑色标签,代表“处理完”),知道里面有个钱包。但你偷偷把钱包从书包里拿了出来,书包里没钱包了。
  1. 这个对象被转移到了“未处理的角落”
    • 专业:被挪走的白色对象,被另一个白色对象(未被扫描,不在待处理队列)引用了。
    • 生活:你把钱包塞进了一个没贴标签的抽屉(白色标签,代表“未处理”),而清洁工不知道这个抽屉里多了个钱包。

结果:清洁工觉得“钱包既不在已处理的书包里,也不在待处理的清单上”,最后把钱包当垃圾扔了——这就是漏标。

二、解决方案:如何避免漏标?

核心逻辑是阻止上述两个条件同时成立,确保所有有用的东西都能被清洁工(回收器)发现。

1. 增量更新:“已处理的东西被动过?重新查!”
  • 专业原理:如果黑色对象(已处理)的引用被修改,就强制将其变回灰色,重新扫描它的所有引用,避免遗漏。
  • 生活例子:规则规定:“只要动过已查完的东西(黑色标签),就必须重新查一遍。”你从书包(黑色)里拿出钱包后,书包自动变回灰色标签。清洁工重新检查书包时,发现你把钱包移到了抽屉,就会顺着去查抽屉,找到钱包。
2. 原始快照:“按刚开始的样子算,不管后来怎么动”
  • 专业原理:标记开始时记录所有对象的引用关系快照,回收器只认快照中的引用,忽略后续修改。
  • 生活例子:清洁工打扫前先给房间拍了张全景照(快照),照片里钱包还在书包里。不管你后来把钱包移到哪,清洁工都按照片里的线索查——既然照片里书包有钱包,就会一直追查,直到找到钱包,不会当垃圾扔。

简单说,漏标就是“回收器没跟上用户线程的修改”导致的误判,解决方案要么是“修改时主动提醒”,要么是“让已处理的对象重新检查”,要么是“按初始状态为准”,最终目的都是确保有用的东西不会被漏掉~

http://www.dtcms.com/a/340677.html

相关文章:

  • LLM常见名词记录
  • 《高中数学教与学》期刊简介
  • 109、【OS】【Nuttx】【周边】效果呈现方案解析:workspaceStorage(下)
  • Pytest项目_day20(log日志)
  • Redis--day9--黑马点评--分布式锁(二)
  • 基于门控循环单元的数据回归预测 GRU
  • 【ansible】3.管理变量和事实
  • 拆分工作表到工作簿文件,同时保留其他工作表-Excel易用宝
  • NAS在初中信息科技实验中的应用--以《义务教育信息科技教学指南》第七年级内容为例
  • AI面试:一场职场生态的数字化重构实验
  • 如何使用matlab将目录下不同的excel表合并成一个表
  • Kafka如何保证「消息不丢失」,「顺序传输」,「不重复消费」,以及为什么会发送重平衡(reblanace)
  • 稳压管损坏导致无脉冲输出电路分析
  • 【Linux仓库】进程等待【进程·捌】
  • week3-[分支嵌套]方阵
  • React15.x版本 子组件调用父组件的方法,从props中拿的,这个方法里面有个setState,结果调用报错
  • setup 函数总结
  • 买卖股票的最佳时机III
  • C++STL-list 底层实现
  • Adobe Adobe Illustrator Ai 2025最新版软件安装包下载与详细图文安装教程!!
  • 代码随想录Day57:图论(寻宝prim算法精讲kruskal算法精讲)
  • 【自动化运维神器Ansible】Roles中Tags使用详解:提升自动化效率的利器
  • STM32 外设驱动模块五:DHT11 温湿度传感器
  • 【Express零基础入门】 | 构建简易后端服务的核心知识
  • 如何查看和修改网络接口参数?
  • 计算机网络模型
  • 2025年Java后端最新场景题+八股文面试题
  • 田野科技“一张皮”,“AI+虚拟仿真”推动考古教学创新发展
  • 晨控EtherCAT设备分配IP操作手册
  • 详细的Git的安装教程