【大白话说Java面试题 第47题】【JVM篇】第7题:Young GC 和 Full GC 分别采用什么算法?

📌 PDF :大白话说Java面试题 --- 02-JVM篇

第7题:Young GC 和 Full GC 分别采用什么算法

📚 回答:

  • 核心概念 :
    JVM 的垃圾回收机制针对不同代(年轻代和老年代)采用了不同的算法,以提高回收效率和减少性能开销。以下是 Young GC 和 Full GC 使用的具体算法及其特点:

1. Young GC 的算法:标记-复制(Mark-Copy)
  • 定义:

    • 将年轻代划分为一个较大的 Eden 区和两个较小的 Survivor 区(From 和 To)。
    • 每次只使用 Eden 区和其中一个 Survivor 区,当内存不足时,触发 Young GC:
      1. 标记存活对象(即未被回收的对象)。
      2. 将存活对象从 Eden 区和 From Survivor 区复制到 To Survivor 区。
      3. 清理 Eden 区和 From Survivor 区的所有空间。
      4. 交换 From 和 To Survivor 区的角色,为下一次 GC 做准备。
  • 优点:

    • 高效清理短生命周期的对象,避免内存碎片化问题。
  • 缺点:

    • 需要额外的 Survivor 区空间,导致内存利用率较低。

    💡 代码示例 :

    以下伪代码展示了标记-复制算法的基本流程:

java 复制代码
// Eden 区和 Survivor 区
Object[] eden = new Object[10];
Object[] survivorFrom = new Object[5];
Object[] survivorTo = new Object[5];

// 标记存活对象并复制到 To Survivor 区
for (Object obj : eden) {
    if (isAlive(obj)) {
        copyToSurvivor(survivorTo, obj);
    }
}

// 清理 Eden 区和 From Survivor 区
eden = new Object[10]; // 清空 Eden 区
survivorFrom = new Object[5]; // 清空 From Survivor 区

2. Full GC 的算法:标记-清除(Mark-Sweep)或标记-整理(Mark-Compact)
  • 标记-清除(Mark-Sweep):

    • 过程 :
      1. 标记所有存活对象。
      2. 统一回收未标记的对象(垃圾对象)。
    • 优点 :
      • 实现简单,适合一次性清理大量垃圾对象。
    • 缺点 :
      • 容易产生内存碎片,影响后续分配大对象的效率。
  • 标记-整理(Mark-Compact):

    • 过程:

      1. 标记所有存活对象。
      2. 将所有存活对象向内存的一端移动,压缩内存空间。
      3. 清理边界以外的空间。
    • 优点:

      • 避免内存碎片化问题,适合频繁分配大对象的场景。
    • 缺点:

      • 整理过程需要额外的时间开销,性能略低于标记-清除。

      💡 源码解析 :
      HotSpot VM 的 SerialGC 和 ParallelGC 默认使用标记-整理算法,而 CMS 使用标记-清除算法。具体实现可以参考 GenCollectedHeap 和 ConcurrentMarkSweepGeneration 模块。


3. 对比总结
算法 适用场景 优点 缺点
标记-复制 年轻代(短生命周期对象) 高效清理垃圾,无内存碎片 需要额外的 Survivor 区,内存利用率低
标记-清除 老年代(少量垃圾对象) 实现简单,适合一次性清理大量垃圾 易产生内存碎片
标记-整理 老年代(频繁分配大对象) 避免内存碎片,适合长期运行的应用 整理过程耗时较长

💡 面试官视角:

  • 面试官可能会问"为什么年轻代使用标记-复制算法?"答:因为年轻代中大多数对象是短生命周期的,标记-复制算法能高效清理垃圾且无碎片问题。
  • 面试官可能会追问"标记-清除和标记-整理的区别是什么?"答:标记-清除直接回收垃圾,容易产生碎片;标记-整理会压缩内存,避免碎片但耗时更长。
相关推荐
打工仔折腾 AI5 分钟前
后端部署避坑:吃透IPv4地址、网络接口与CIDR前缀的实际应用
arm开发·人工智能·后端·python·性能优化
街头便衣10 分钟前
OpenRouter周榜复算:164万亿token,输出2.55%,DeepSeek账单占1.4%
android·java·开发语言·人工智能·语言模型·开源
Mortalbreeze11 分钟前
0 - 1 BFS 算法详解:从基本原理到经典题目建模
数据结构·c++·算法·图论·宽度优先
mister_guo14 分钟前
Spring Boot 配置文件读取的几种方式:用法、原理与常见误区
java·spring boot
余槐i15 分钟前
虚拟线程上线后吞吐反而掉了:Spring Boot 3 里 synchronized 锁住载体线程的定位与修复
java·spring boot·性能优化·虚拟线程·jdk 21
要开心吖ZSH18 分钟前
DDD(领域驱动设计)篇三:实战对照——同一个订单业务,两种架构怎么写
java·架构·领域模型·ddd·领域驱动设计·设计思想
飞Link2 小时前
什么是 PX4?一文了解 PX4 在空地协同中的作用
算法·无人机
独泪了无痕8 小时前
Spring Data Redis 快速上手
spring boot·redis·后端
一去不复返的通信er8 小时前
力扣-图论-岛屿数量
算法·leetcode·图论