标记-整理算法:对象移动与指针更新逻辑

夜浩小哥_2123

夜浩小哥_2123

2026-07-28

963人浏览

原创

标记-整理算法(mark-compact)先标记所有可达对象,再将存活对象顺序搬移到堆的一端以消除碎片,最后统一更新所有指向旧地址的引用。

标记-整理算法:对象移动与指针更新逻辑

标记-整理算法(Mark-Compact)在垃圾回收中通过“标记”存活对象、“整理”内存空间来消除碎片。其核心在于:先遍历并标记所有可达对象,再将它们顺序搬移到内存一端,最后批量更新所有指向这些对象的指针。

标记阶段:识别存活对象

从根集合(如栈帧、寄存器、静态变量)出发,用深度优先或广度优先遍历对象图,为每个可达对象打上标记位(如对象头中一个 bit)。未被标记的对象即判定为垃圾,后续不参与移动。

  • 标记过程不修改对象内容,仅设置标识,开销相对可控
  • 需保证并发场景下标记一致性(如使用三色标记或写屏障)
  • 标记完成后,可快速统计存活对象总数和总大小,用于规划整理区域

整理阶段:按序搬移存活对象

从堆起始地址开始扫描,维护一个“目标位置”指针(如 freePtr),每遇到一个已标记对象,就将其完整复制到 freePtr 所指位置,然后将 freePtr 向后推进该对象大小。

PhotoStudio AI
PhotoStudio AI

PhotoStudio AI是虹软科技推出的电商 AI 智能商拍服务平台。

下载
  • 搬移顺序通常与原始内存布局一致(保持局部性),也可按对象大小分组以优化缓存友好性
  • 对象复制时需保持字段对齐、保留元数据(如类指针、哈希码等)
  • 搬移后原位置可直接清零或留作下次分配起点,无需单独清理

指针更新阶段:修正所有引用

整理完成后,所有存活对象已紧凑排列,但程序中仍存在大量指向旧地址的引用(如栈、寄存器、其他对象字段)。必须遍历所有可能含指针的位置,将旧地址替换为新地址。

  • 常用方法是预先记录每个对象的“移动映射”:旧地址 → 新地址(可用哈希表或位图压缩存储)
  • 栈和寄存器中的指针由 GC 线程直接扫描并更新;堆内引用则遍历所有存活对象的字段逐个修正
  • 现代实现常结合“卡片标记”或“写屏障”减少需扫描范围,避免全堆遍历

关键细节:移动与更新的协同保障

移动和更新必须严格有序:不能在对象尚未搬完时就开始更新指针,否则会引用到中间状态;也不能延迟更新导致程序读到失效地址。

  • 典型做法是两阶段执行:第一阶段只搬移,第二阶段统一更新——确保原子性
  • 部分 JVM 实现(如 Serial GC)采用“滑动压缩”,边搬移边计算新地址,但更新仍集中进行
  • 若支持并发整理,需额外机制(如读屏障)拦截访问,防止程序看到半移动对象

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

359

31

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

2023.08.14

5736

4

Revel框架模板渲染与表单验证
Revel框架模板渲染与表单验证

本专题围绕Revel框架视图层开发,介绍模板语法、变量输出、布局复用、表单提交、参数绑定与验证规则,帮助开发者完成安全规范的页面交互。

2026.10.16

0

15

Revel框架MVC路由与控制器
Revel框架MVC路由与控制器

本专题聚焦Revel框架MVC核心机制,讲解路由定义、控制器Action、参数绑定、请求响应和反向路由,并结合常见场景梳理接口请求处理流程。

2026.10.16

0

15

Revel框架入门与安装配置
Revel框架入门与安装配置

本专题从Revel框架环境搭建讲起,系统介绍命令行工具安装、项目创建、目录结构、配置文件及热代码重载,帮助开发者快速完成首个Go Web应用。

2026.10.16

0

15

Linux 新手先学哪些命令
Linux 新手先学哪些命令

Linux新手命令专题汇集终端基础、文件目录操作、文本查看、软件安装和权限管理等入门文章,帮助按实际任务练习常用命令并建立命令行操作习惯。

2026.10.15

0

20

MySQL 忘记密码怎么办
MySQL 忘记密码怎么办

MySQL忘记密码专题汇集不同版本与系统下的root密码重置方法,覆盖MySQL 5.7、8.0、Mac、Linux及本地集成环境,并提示恢复权限与重新登录的检查步骤。

2026.10.15

0

18

Vue.js 中 ref 和 reactive 的区别
Vue.js 中 ref 和 reactive 的区别

Vue.js中ref和reactive的区别专题汇集两种响应式API的定义、访问方式、对象解构、侦听与性能取舍等文章,帮助结合实际状态类型选择合适写法。

2026.10.15

0

20

VS Code 怎么配置开发环境
VS Code 怎么配置开发环境

VS Code开发环境专题汇集编辑器安装、语言扩展、编译器、解释器、终端和调试配置文章,覆盖Java、Python、C++和PHP等常见语言的入门设置。

2026.10.15

0

18

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
php-src源码分析探索
php-src源码分析探索

共6课时 | 0.7万人学习

Golang云原生架构师课程
Golang云原生架构师课程

共49课时 | 4.8万人学习

Golang基础入门到精通(第二季)
Golang基础入门到精通(第二季)

共49课时 | 4.7万人学习