常见的【垃圾收集算法】

目录

      • [1. 标记 - 清除算法(Mark-Sweep)](#1. 标记 - 清除算法(Mark-Sweep))
      • [2. 复制算法(Copying)](#2. 复制算法(Copying))
      • [3. 标记 - 整理算法(Mark-Compact)](#3. 标记 - 整理算法(Mark-Compact))

1. 标记 - 清除算法(Mark-Sweep)

自己的理解:

标记清除算法:从GC root出发扫描,并标记所有存活的对象,之后清除没有标记的对象。

优点是:核心流程简单;

缺点是:导致内存碎片化严重(无法分配需要连续空间的大对象,例如数组)。在可回收的对象(垃圾对象)多时,大量的标记清除特别耗时(由于标记过程需要全堆遍历,会使得 GC 停顿时间较长,比较耗时)

注意:标记用的是三色标记法

更专业一点:

复制代码
标记 - 清除算法是通过 GC Roots 扫描标记存活对象,回收未标记对象的垃圾回收算法。
其核心流程简洁,但存在明显缺陷:标记阶段全堆遍历,对象数量多时常导致 GC 停顿久;回收后产生的内存碎片化,会引发大对象分配失败、后续内存分配和垃圾回收效率降低等问题。
该算法常应用于对停顿时间要求不是极端严格,且能通过其他机制一定程度缓解碎片化影响的场景(如老年代部分垃圾回收场景),同时也因这些特点,在与复制算法、标记 - 整理算法的对比中,有独特的适用范围和权衡考量。
  • 流程:

    1. 标记:遍历对象图,标记所有存活对象。
    2. 清除:遍历堆内存,回收未标记的对象(直接释放内存)。
  • 优缺点:

    • 优点:实现简单,无需移动对象。

    • 缺点:产生内存碎片 (零散的空闲内存无法分配大对象(数组));标记和清除过程耗时(全堆遍历)。

2. 复制算法(Copying)

自己的理解:

标记-复制算法:将内存分为两个大小相同的区域,每次只使用其中一个,当垃圾回收时将存活的对象复制到另一块区域,然后清除正在使用的区域。

优点是无内存碎片。

缺点是:首先当一个区域存活的对象太多时,需要较多的内存间复制,效率低。

第二个是浪费内存,每次只使用一半的内存。特别适合新生代,因为新生代每次存活的对象少,复制就少,性能影响就不那莫明显。

补充:

java 复制代码
HotSpot 里新生代用 8:1:1 的 Eden+Survivor 结构,本质也是这种算法的优化,既保留无碎片优势,又提高了内存利用率
  • 流程
    将内存分为两块等大区域 (如新生代的 Eden + s0、s1),每次只用其中一块。回收时,将存活对象复制到另一块空白区域,然后清空当前区域。

  • 优缺点:

    • 优点:无内存碎片,适合存活率低的区域(如新生代)。
    • 缺点:浪费内存 (使现有得可用空间变为原来得一半);复制对象有性能开销(小对象影响小,大对象成本高)。

    3. 标记 - 整理算法(Mark-Compact)

自己的理解:

标记-整理算法:标记过程和标记清除过程一样,首先是从GC Roots出发标记存活的对象,但后续过程它是将存活的对象移到内存一端,然后直接清除边界以外的内存。

优点是解决了内存碎片的问题,缺点是需要移动对象,可能有性能开销。

更全面一点:

复制代码
"标记 - 整理算法的标记阶段和标记 - 清除一致,都是从 GC Roots 出发标记存活对象。但后续它会把存活对象移动到内存的一端,然后清除边界外的所有内存。
优点是彻底解决了内存碎片化问题,避免大对象分配失败;缺点是移动对象时需要修改引用地址,可能带来性能开销,尤其是存活对象多的时候。
这种算法很适合老年代,因为老年代对象存活率高,用复制算法成本太高,用标记 - 清除会有碎片,而标记 - 整理能平衡这两点,虽然有移动成本,但老年代回收频率低,整体更合理。"
相关推荐
Java小生不才28 分钟前
Spring AI文生音
java·人工智能·spring
凯尔萨厮31 分钟前
Springboot2.x+Thymeleaf项目创建
java
fish_xk43 分钟前
map和set
java·开发语言
李崧正1 小时前
Java技术分享:Lambda表达式与函数式编程
java·开发语言·python
老了,不知天命1 小时前
鳶尾花項目JAVA
java·开发语言·机器学习
二哈赛车手1 小时前
新人笔记---实现简易版的rag的bm25检索(利用ES),以及RAG上传时的ES与向量数据库双写
java·数据库·笔记·spring·elasticsearch·ai
winner88811 小时前
从零吃透C++命名空间、std、#include、string、vector
java·开发语言·c++
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题】【Java基础篇】第26题:Java的抽象类和接口有哪些区别
java·开发语言·面试
bzmK1DTbd1 小时前
SOLID原则在Java中的实践:单一职责与开闭原则
java·开发语言·开闭原则
winner88812 小时前
C++ 命名空间、虚函数、抽象类、protected 权限全套通俗易懂精讲(附与 Java 对比)
java·开发语言·c++