JVM(Java虚拟机)的垃圾回收器(Garbage Collector, GC)是管理内存自动回收的核心组件,负责回收不再使用的对象,释放内存空间。JVM提供了多种垃圾回收器,每种回收器都有其特定的适用场景和性能特点。
垃圾回收器的分类
按工作区域划分
新生代回收器:负责回收新生代(Young Generation)的内存;
老年代回收器:负责回收老年代(Old Generation)的内存;
整堆回收器:同时负责新生代和老年代的内存回收。
按工作方式划分
串行回收器(Serial GC):单线程执行垃圾回收,适合单核CPU或小型应用;
并行回收器(Parallel GC):多线程执行垃圾回收,适合多核CPU和高吞吐量场景;
并发回收器(Concurrent GC):在应用程序运行的同时执行部分垃圾回收工作,适合低延迟场景。
常见的垃圾回收器
Serial GC
特点
单线程执行垃圾回收。
在垃圾回收时会暂停所有应用线程(Stop-The-World)。
适用场景:单核CPU或客户端应用。
启用参数:
-XX:+UseSerialGC
Parallel GC(吞吐量优先)
特点
多线程执行垃圾回收。
关注高吞吐量,适合后台计算任务。
适用场景:多核CPU、高吞吐量应用。
启用参数:
-XX:+UseParallelGC
CMS GC(Concurrent Mark-Sweep)
特点
并发执行大部分垃圾回收工作,减少停顿时间。
采用"标记-清除"算法,可能产生内存碎片。
适用场景:低延迟应用,如Web服务器。
启用参数:
-XX:+UseConcMarkSweepGC
(在JDK 9及以上版本已弃用)
G1 GC(Garbage-First)
特点
将堆内存划分为多个区域(Region),优先回收垃圾最多的区域。
兼顾吞吐量和低延迟。
适用场景:大内存、多核CPU的应用。
启用参数:
-XX:+UseG1GC
ZGC(Z Garbage Collector)
特点
支持超大堆内存(TB级别)。
停顿时间极短(通常不超过10ms)。
适用场景:超大内存、低延迟应用。
启用参数:
-XX:+UseZGC
(需要JDK 11及以上版本)
Shenandoah GC
特点
与ZGC类似,专注于低停顿时间。
与ZGC相比,Shenandoah GC在JDK 12中成为正式特性。
适用场景:低延迟、大内存应用。
启用参数:
-XX:+UseShenandoahGC
(需要JDK 12及以上版本)
垃圾回收器的工作原理
垃圾回收器的工作通常分为以下几个阶段:
标记(Mark)
遍历堆内存,标记所有存活的对象;
从GC Roots(如栈帧、静态变量等)开始,递归标记所有可达对象。
清除(Sweep)
回收未被标记的对象,释放内存空间;
在“标记-清除”算法中,可能会产生内存碎片。
压缩(Compact)
将存活对象移动到内存的一端,消除内存碎片,在“标记-整理”算法中使用。
复制(Copy)
将存活对象从一个内存区域复制到另一个区域,在新生代的垃圾回收中常用。
垃圾回收器的调优
通过调整JVM参数,可以优化垃圾回收器的性能。以下是一些常见的调优参数:
堆大小
-Xms
:初始堆大小;-Xmx
:最大堆大小。
新生代大小
-XX:NewSize
:初始新生代大小;-XX:MaxNewSize
:最大新生代大小。
GC日志
-XX:+PrintGCDetails
:打印GC详细信息;-Xloggc:<file>
:将GC日志输出到文件。
示例
以下是一个启用G1 GC的JVM参数示例:
java -XX:+UseG1GC -Xms512m -Xmx2g -XX:MaxGCPauseMillis=200 -jar app.jar
-XX:+UseG1GC
:启用G1 GC;-Xms512m
:初始堆大小为512MB;-Xmx2g
:最大堆大小为2GB;-XX:MaxGCPauseMillis=200
:设置最大停顿时间为200ms。