JVM垃圾回收算法主要有标记-清除、复制和标记-整理三种,分别适用于不同内存区域。标记-清除易产生碎片,复制算法以空间换时间,适合新生代,标记-整理则解决碎片问题,适合老年代。JVM结合多种算法,基于对象生命周期差异实现分代回收,提升性能。现代GC器如G1、ZGC、Shenandoah通过区域化管理、并发处理和读屏障等技术,在大堆场景下实现低延迟与高吞吐的平衡。选择合适的GC器需根据应用类型、堆大小、对象分配速率和硬件资源综合考量,并通过日志分析与调优持续优化。

JVM的垃圾回收算法主要有三种基本类型:标记-清除(Mark-Sweep)、复制(Copying)和标记-整理(Mark-Compact)。它们各自有其优缺点,并且在实际的JVM实现中,往往会结合使用,以适应不同的内存区域和回收需求。
要说JVM的垃圾回收,首先得明白它核心的那几个套路。在我看来,所有复杂的GC器,骨子里都离不开这三种基本算法的影子,只是它们被包装得更精巧,或者说,有了更高级的优化策略。
标记-清除(Mark-Sweep)算法 这是最基础的一种,理解起来也直观。它分两步走:
复制(Copying)算法 这个算法的思路就完全不同了,它更像是一种“以空间换时间”的策略,特别适合那些生命周期短的对象。它将可用内存分成大小相等的两块,每次只使用其中一块。当这块内存用完了,就将还“活着”的对象复制到另一块空闲的内存上,然后把当前使用的这块内存全部清理掉。
标记-整理(Mark-Compact)算法 标记-整理是标记-清除的升级版,它在标记之后,并没有直接清除,而是多了一步“整理”。
你可能会问,既然有这么多算法,为什么不选一个最好的用到底?我的理解是,没有“最好”的算法,只有“最合适”的算法。JVM之所以需要多种垃圾回收算法,并让它们协同工作,核心原因在于对象的生命周期差异和性能目标的多样性。
设想一下,你有一个繁忙的办公室,有些文件(对象)刚用完就扔了,有些文件要长期保存。如果用同一种方式处理,效率肯定不高。JVM正是基于这种“分代假设”(Generational Hypothesis)来设计的:绝大多数对象都是朝生夕死的,而少数对象会长期存活。
因此,JVM把堆内存分成了不同的区域,最常见的就是新生代(Young Generation)和老年代(Old Generation)。
这种分代协同的策略,本质上是一种优化:用最适合的算法处理最合适的区域。新生代用复制,追求高吞吐量和低延迟;老年代用标记-整理或更复杂的算法,解决碎片和长期存活对象的回收问题。它们就像是流水线上的不同工位,各司其职,共同完成了垃圾回收这个大任务,以最小的代价维持了应用的持续运行。
如果说前面讲的是GC算法的“基本功”,那么现代JVM的垃圾回收器就是这些基本功的集大成者,并且加入了大量创新,旨在解决传统GC器面临的痛点。我们追求的无非是两点:高吞吐量(单位时间内处理更多任务)和低延迟(响应时间快)。但这两者往往是鱼和熊掌,难以兼得。
CMS(Concurrent Mark Sweep)收集器: CMS是HotSpot JVM中第一个真正意义上的并发收集器,它的目标是降低GC时的停顿时间(latency),特别适用于对响应时间敏感的Web应用。它主要用于老年代。 它的核心思想是:在标记和清除阶段,尽可能地让GC线程和应用线程并发执行,减少STW时间。它有几个关键步骤:初始标记(STW,但很快)、并发标记(与应用并发)、重新标记(STW,修正并发标记期间对象的变化)、并发清除(与应用并发)。 听起来很美,但CMS也有它的问题:
G1(Garbage-First)收集器: G1是Oracle在JDK 7中推出的,旨在取代CMS,成为下一代低延迟、高吞吐量的收集器。它的设计理念非常独特:它将整个Java堆划分为多个大小相等的独立区域(Region)。每个Region都可以独立地作为Eden、Survivor或者Old区。 G1的核心优势在于:
ZGC和Shenandoah收集器: 这是JDK 11之后出现的,代表了JVM GC的最新发展方向,它们的目标是将GC停顿时间控制在极低的水平(通常是10毫秒以内,甚至更低),即便是在TB级别的堆内存下也能保持。它们的核心技术突破在于使用了着色指针(Colored Pointers)和读屏障(Read Barriers)。 简单来说,它们通过在指针中编码GC状态信息,并在每次对象访问时插入读屏障来检测并处理并发GC操作,从而实现了几乎完全并发的垃圾回收。这意味着GC的绝大部分工作可以与应用线程并发执行,STW时间极短,几乎可以忽略不计。
选择一个合适的垃圾回收器,就像是为你的汽车选择合适的轮胎,得看路况和驾驶习惯。没有万能的答案,只有最适合你应用场景的那个。
在做决策时,我通常会考虑以下几个核心因素:
应用类型和性能目标:
堆内存大小:
对象分配和晋升速率:
硬件资源:
调优策略的一些考量点:
-Xms和-Xmx:设置堆的初始和最大大小。通常建议设为相同值,避免运行时堆的动态扩展和收缩带来的额外开销。-XX:+UseG1GC:启用G1收集器。-XX:MaxGCPauseMillis=200:为G1设置目标停顿时间。-XX:NewRatio 或 -Xmn:调整新生代和老年代的比例或直接指定新生代大小。这对于控制新生代GC频率和对象晋升速度很有用。-XX:+PrintGCDetails 和 -XX:+PrintGCDateStamps:开启详细GC日志,这是GC调优的基石。没有日志,一切都是盲猜。总之,选择和调优JVM垃圾回收器是一个持续迭代的过程。它需要你理解应用本身的特性,结合GC算法的原理,通过参数调整和数据分析,最终找到一个最适合你系统的平衡点。这就像是打磨一件工具,越了解它,越能让它发挥出最大的效用。
以上就是说一下jvm 有哪些垃圾回收算法?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号