1. 概述#
本博客中我们将展示不同JVM垃圾回收(GC)实现的基本原理。然后我们将学习如何在应用程序中启动特定类型的垃圾回收。
2. 垃圾回收简介#
看到这个名字,你可能会想:“垃圾回收是什么?
”简单来说,垃圾回收是Java虚拟机(JVM)用来自动管理内存的过程。它的主要任务是识别和清除不再被程序使用的对象,从而释放内存空间,防止内存泄漏和优化应用程序性能。
基本上GC会以两个简单的步骤工作:
- 标记(Marking):GC会扫描内存,标记所有仍然被引用的对象。
- 清除(Sweeping):GC会清除未被标记的对象,释放它们占用的内存空间。
2.1 优点#
- 自动内存管理:开发者不需要手动分配/释放内存,未使用的空间会被自动回收。
- 无需处理野指针(Dangling Pointer):GC可以防止野指针问题,减少内存错误的发生。
- 自动管理内存泄漏:垃圾回收器能自动处理大部分的内存泄漏问题。
- 提高开发效率:开发者可以专注于业务逻辑,而不必过多关注内存管理细节。
2.2 缺点#
- CPU资源消耗:由于JVM必须持续监控对象引用的创建与销毁,监控过程会消耗更多的CPU资源,对于需要大内存的请求来说,垃圾回收器的运行会影响应用程序的性能。
- 缺乏调度控制权:开发者无法控制JVM何时分配CPU时间分片来清理不需要的对象,无法人为干预GC调度。
- 停顿时间(Stop-the-World):垃圾回收过程可能会导致应用程序暂停,某些GC实现方案可能会引起较长的停顿时间,影响应用程序的响应性。
- 效率限制:自动管理内存可能不如手动分配与释放内存高效,尤其是在高性能应用中。
3. GC进化路程与常见算法#
Java的垃圾回收机制(Garbage Collection,GC)经历了多次演变和改进,以提高性能、减少停顿时间以及更好地适应不同类型的应用程序需求。
从早期的Serial GC到现代的低延迟GC,Java提供了多种垃圾回收器以满足不同场景的需求。下面将按照进化顺序介绍各种GC实现。
3.1 Serial GC(串行垃圾回收器)#
特点:
- 最早的GC实现,适用于单线程环境。
- 使用单线程进行垃圾回收,适合小型应用程序,但在多核处理器上表现不佳。
- 停顿时间较长,影响应用程序的响应性。
- 适用于内存较小且对响应时间要求不高的应用。
命令行参数:
java -XX:+UseSerialGC -jar Application.java备注: Twitter 的工程师在 QCon 2012 上曾就 Serial GC 的性能发表过精彩演讲,这是深入了解该回收器的一个很好途径。
3.2 Parallel GC(并行垃圾回收器,Throughput Collector)#
特点:
- 引入多线程垃圾回收,提高了吞吐量。
- 适用于多核处理器,能够更有效地利用系统资源。
- 仍然存在停顿时间,但相较于Serial GC有所减少。
- 适用于对吞吐量要求较高的应用程序。
命令行参数:
java -XX:+UseParallelGC -jar Application.java3.3 CMS(Concurrent Mark-Sweep)GC#
特点:
- 旨在减少停顿时间,通过并发标记和清除来实现。
- 在标记阶段与应用程序线程并发运行,减少了停顿时间。
- 适用于对响应时间要求较高的应用程序,如Web服务器。
- 可能会导致内存碎片化问题。
命令行参数:
java -XX:+UseConcMarkSweepGC -jar Application.java3.4 G1(Garbage-First)GC#
特点:
- 设计用于大内存应用程序,能够更好地管理堆内存。
- 将堆划分为多个区域,优先回收垃圾最多的区域。
- 提供可预测的停顿时间,适用于对响应时间有严格要求的应用程序。
- 通过并发和并行处理提高了垃圾回收效率。
命令行参数:
java -XX:+UseG1GC -jar Application.java3.5 ZGC(Z Garbage Collector)#
特点:
- 低延迟垃圾回收器,适用于大内存和多核处理器环境。
- 采用并发标记和压缩技术,最大停顿时间通常在几毫秒级别。
- 支持数TB级别的堆内存。
- 适用于对延迟敏感的应用程序,如实时系统。
命令行参数:
java -XX:+UseZGC -jar Application.java3.6 Shenandoah GC#
特点:
- 另一种低延迟垃圾回收器,类似于ZGC。
- 通过并发标记和压缩,减少停顿时间。
- 适用于大内存应用程序,支持多TB级别的堆内存。
命令行参数:
java -XX:+UseShenandoahGC -jar Application.java3.7 Epsilon GC#
特点:
- 无操作垃圾回收器,不进行实际的垃圾回收。
- 适用于性能测试和内存压力测试场景。
- 允许开发者观察应用程序在没有GC干扰下的行为。
命令行参数:
java -XX:+UseEpsilonGC -jar Application.java4. 总结#
Java GC的进化反映了对不同应用需求的响应,从早期的简单实现到现代的低延迟、高吞吐量的垃圾回收器。选择合适的GC策略取决于应用程序的特性和性能要求:
- 小型应用、单核环境:Serial GC
- 吞吐量优先、多核环境:Parallel GC
- 响应时间优先、中等堆内存:CMS GC 或 G1 GC
- 大内存、低延迟要求:ZGC 或 Shenandoah GC
- 性能测试、基准测试:Epsilon GC
随着Java的发展,GC技术将继续演进,以满足不断变化的计算需求。
通过邮件回复



