Java中的垃圾回收(Garbage Collection, GC)是一种自动内存管理机制,用于自动回收不再使用的对象所占用的内存空间。Java虚拟机(JVM)提供了几种不同的垃圾收集算法,每种算法都有其特点和适用场景。下面是一些常见的垃圾回收算法及其工作原理:
1. 标记-清除算法 (Mark-Sweep)
这是最基础的垃圾回收算法。它分为两个阶段:
- 标记阶段:从根节点开始遍历整个对象图,标记所有可达的对象。
- 清除阶段:清理未被标记的对象,这些对象被视为垃圾。
缺点:
- 清除后会产生大量不连续的内存碎片。
- 执行过程中需要暂停应用程序。
2. 标记-整理算法 (Mark-Compact)
这是一种改进版的标记-清除算法,除了标记和清除之外,还增加了整理内存的功能:
- 标记:与标记-清除算法相同。
- 整理:将存活的对象压缩到内存的一端,然后直接清理掉末端的空白区域。
优点:
- 解决了内存碎片的问题。
3. 复制算法 (Copying)
复制算法将可用内存分成两个相等的部分(称为从区和至区)。每次只使用其中的一个区域,在垃圾回收时,将存活的对象复制到另一个空闲区域中,然后清空当前区域。
优点:
- 不会产生内存碎片。
- 每次只需要处理半个区域。
缺点:
- 内存利用率只有50%。
4. 分代收集算法 (Generational Collection)
基于这样一个观察:绝大多数对象都是朝生夕死的。因此,可以将堆分为几个不同的区域(代),比如新生代(Young Generation)和老年代(Old Generation)。
- 新生代:采用复制算法,因为大多数对象很快就会死亡。
- 老年代:采用标记-清除或标记-整理算法,因为对象存活率高。
5. 增量收集算法 (Incremental Collection)
该算法试图把一个完整的GC动作分成若干个小的动作来完成,每次只完成一部分,从而减少长时间的暂停。
6. 并行收集算法 (Parallel Collection)
该算法利用多处理器或多线程技术来执行垃圾回收,多个CPU同时工作,提高效率。
7. 并发收集算法 (Concurrent Collection)
这种算法允许垃圾收集和应用程序交替执行,以减少应用程序的暂停时间。例如,CMS(Concurrent Mark Sweep)收集器和G1(Garbage First)收集器。
8. 停顿时间优先收集算法 (Pause Time Priority Collection)
如G1收集器,它的目标是最小化停顿时间,适用于交互式应用。
9. 吞吐量优先收集算法 (Throughput Priority Collection)
这类收集器的目标是最大化应用程序的运行时间,减少垃圾收集的时间占比,适合后台批处理任务。
Java虚拟机的默认选择
不同的JVM版本和配置可能有不同的默认垃圾收集器。例如,在Java 8中,CMS收集器是较常使用的选项之一,而在Java 11及以后的版本中,G1收集器逐渐成为默认选择。
每种算法都有其优缺点,实际应用中需要根据系统的具体需求来选择合适的垃圾收集策略。