标记-整理算法通过移动存活对象至内存一端并紧凑排列,消除老年代碎片,形成连续空闲区,支持大对象分配,并同步更新所有引用以保证安全性,兼顾空间效率与长期分配稳定性。

Java 标记-整理算法通过“移动存活对象 + 归拢内存布局”的方式,从物理层面直接消除老年代内存碎片,而不是在碎片基础上做修补。
把所有存活对象统一搬到内存一端
整理阶段不是清理完就结束,而是将所有已标记的存活对象(无论大小、类型)按顺序紧凑迁移到内存起始端(如低地址侧)。迁移后,这些对象连续排列,中间不留空洞。比如一个 1.2MB 的缓存对象和几十个几百字节的配置对象,都会被挨个拼接安置,形成一段致密的已用区。
一次性释放整段尾部空闲空间
整理完成后,内存自然分成两块:前端是紧凑的存活区,后端是完全连续的空闲区。GC 只需把分配指针(如 bump-the-pointer)重置到存活区末尾,后续所有新对象都可顺序分配,无需查找、拼凑或管理空闲链表。这样即使需要分配 2MB 的大数组,也能立刻满足,不会因“总空闲够但分散”而失败。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
同步更新所有引用,保证对象位置变更安全
移动对象时,JVM 会扫描并修正所有指向它的引用,包括:
- 栈帧中的局部变量
- 其他对象的字段(如 HashMap 的 table 数组引用了某个 Entry)
- 静态字段和常量池条目
这确保移动后程序逻辑不受影响,也避免了因引用未更新导致的内存错误或崩溃。
只动存活对象,开销可控且长期收益高
相比复制算法要预留双倍空间、拷贝全部存活数据,标记-整理只在原有老年代内操作,不额外占用堆空间;相比标记-清除放任碎片累积,它用一次 STW 内的整理代价,换来长期稳定的连续分配能力。尤其适合老年代中 80%–95% 对象长期存活、又常需容纳大对象的场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










