垃圾收集算法了解吗?

JVM 中的垃圾收集(GC)算法核心是高效识别并回收无用对象内存,主流算法按"回收逻辑"可分为 4 类,各有适用场景,目前商用 JVM 多采用组合算法(如分代收集):

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

  • 核心步骤:分"标记"和"清除"两阶段。

    markdown 复制代码
      1. 标记:通过可达性分析,标记所有存活对象;
    
      2. 清除:遍历堆内存,回收所有未被标记的无用对象,释放内存。
  • 优点:实现简单,无需移动对象。

  • 致命缺点:

    复制代码
      ◦ 内存碎片:回收后会产生大量不连续的空闲内存块,后续分配大对象时可能因找不到足够连续空间,触发频繁 GC;
    
      ◦ 效率低:标记和清除都需遍历全堆,堆内存越大,耗时越长。
  • 适用场景:少量内存区域(如 CMS 收集器的老年代)。

2. 复制算法(Copying):解决碎片问题

• 核心步骤:将堆内存划分为大小相等的两块(如 From 区和 To 区),只使用其中一块。

css 复制代码
1. 标记复制:标记 From 区的存活对象,将其复制到 To 区(按顺序排列,无碎片);

2. 交换角色:清空 From 区,后续使用 To 区作为新的 From 区,原 From 区变为 To 区。
  • 优点:无内存碎片,分配内存时只需"指针碰撞",效率高。

  • 缺点:

    复制代码
      ◦ 内存利用率低:仅能使用一半堆内存(如 100MB 堆,实际可用 50MB);
    
      ◦ 复制开销:存活对象多时,复制操作耗时增加。
  • 适用场景:存活对象少的区域(如 HotSpot 年轻代的 Eden 区+Survivor 区,采用 8:1:1 比例优化利用率)。

3. 标记-整理算法(Mark-Compact):兼顾碎片与利用率

  • 核心步骤:在"标记-清除"基础上增加"整理"阶段,解决碎片问题。

    1. 标记:同标记-清除,标记存活对象;

    2. 整理:将所有存活对象向堆内存一端移动,按顺序排列;

    3. 清除:直接清除移动后边界以外的所有无用内存(无需遍历全堆)。

  • 优点:无内存碎片,内存利用率 100%(无需划分两块区域)。

  • 缺点:

    vbnet 复制代码
      ◦ 移动开销:移动存活对象时需更新所有引用指向(如对象头的指针),耗时比标记-清除长;
    
      ◦ STW(Stop The World)时间长:移动过程中需暂停所有用户线程,影响应用响应。
  • 适用场景:存活对象多的区域(如 G1 收集器的老年代、Serial Old 收集器)。

4. 分代收集算法(Generational Collection):商用主流组合算法

  • 核心思想:根据对象"生命周期长短",将堆分为年轻代(短期存活)和老年代(长期存活),对不同区域采用适配的算法,兼顾效率与利用率。

    复制代码
      ◦ 年轻代:对象存活时间短(如临时变量),采用复制算法(存活少,复制开销低,无碎片);
    
      ◦ 老年代:对象存活时间长(如单例、缓存),采用标记-清除或标记-整理算法(存活多,避免复制开销,容忍一定碎片或接受整理耗时)。
  • 优点:结合不同算法的优势,是目前 HotSpot、OpenJDK 等商用 JVM 的默认 GC 策略(如 Parallel Scavenge+Parallel Old、G1、ZGC 均基于分代思想优化)。

相关推荐
李慕婉学姐17 分钟前
【开题答辩过程】以《基于Android的出租车运行监测系统设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·后端·vue
m0_7400437325 分钟前
SpringBoot05-配置文件-热加载/日志框架slf4j/接口文档工具Swagger/Knife4j
java·spring boot·后端·log4j
招风的黑耳1 小时前
我用SpringBoot撸了一个智慧水务监控平台
java·spring boot·后端
Miss_Chenzr2 小时前
Springboot优卖电商系统s7zmj(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
期待のcode2 小时前
Springboot核心构建插件
java·spring boot·后端
2501_921649492 小时前
如何获取美股实时行情:Python 量化交易指南
开发语言·后端·python·websocket·金融
serendipity_hky2 小时前
【SpringCloud | 第5篇】Seata分布式事务
分布式·后端·spring·spring cloud·seata·openfeign
五阿哥永琪3 小时前
Spring Boot 中自定义线程池的正确使用姿势:定义、注入与最佳实践
spring boot·后端·python
Victor3563 小时前
Netty(16)Netty的零拷贝机制是什么?它如何提高性能?
后端
Victor3563 小时前
Netty(15)Netty的线程模型是什么?它有哪些线程池类型?
后端