JVM垃圾收集器

1 概述

垃圾收集器是垃圾回收算法的具体实现。

2 垃圾收集器

2.1 关系图

在这里插入图片描述

2.2 垃圾收集器简略列举

名称使用算法使用位置组合特点
Serial复制算法新生代1.Serial Old
2.CMS
1. 单线程
2.Client模式下默认
3.单CPU下效率高(没有线程切换)
ParNewSerial的多线程版本新生代1.Serial Old
2.CMS
1.多线程
Parallel Scavenge复制算法新生代1.Serial Old
2.Parallel Scavenge
1.-XX:MaxGCPauseMillis=最大GC停顿目标
2.-XX:GCTimeRatio=用户线程/GC目标
3.-XXUseAdaptiveSizePolicy配合1&2实现自适应调节
CMS标记清理算法老年代1.Serial
2.ParNew
3.Serial Old
1.失败后使用Serial Old进行收集
2.浮动垃圾无法处理
3.内存碎片问题
Serial Old标记整理-1.Serial
2.ParNew
3.CMS
其余基本与Serial一样
Parallel Old标记整理老年代Parallel ScavengeParallel Scavenge+Parallel Old组成吞吐量优先收集器组合
G1标记整理+复制各Region-堆内存较大(>6GB)时可考虑,如果现有收集器组合没什么问题,一般不需要调整

3.相关参数(JAVA8)

3.1垃圾收集相关参数

参数描述
UseSerialGCClient模式默认值,Serial + Serial Old组合
UseParNewGCParNew + Serial Old组合
UseConcMarkSweepGCParNew + CMS + Serial Old, Serial Old为CMS失败时的备选方案
UseParallelGCParallel Scavenge + Parallel Old
UseParallelOldGCParallel Scavenge + Parallel Old
SurvivorRatioEden:Survivor,默认8:1
PretenureSizeThreshold直接进入老年代的对象大小
MaxTenuringThreshold晋升到老年代的年龄。对象每坚持过一次Minor GC,年龄+1
UseAdaptiveSizePolicy动态调整各个区域的大小及进入老年代的年龄
HandlePromotionFailure是否允许分配担保失败,即老年代的剩余空间不足以应付新生代的整个Eden区和Survivor区的所有对象都存活的极端情况
ParallelGCThreads设置并行GC的线程数
GCTimeRatio配合Parallel Scavenge,设置用户线程与GC的时间比值,默认99
MaxGCPauseMillis配合Parallel Scavenge,设置GC的最大停顿时间
CMSInitiatingOccupancyFraction设置CMS收集器在老年代被使用多少后出发垃圾收集。默认68%
UseCMSCompactAtFullCollection设置CMS收集器完成垃圾收集后是否要进行一次内存碎片整理
CMSFullGCsBeforeCompaction设置CMS收集器在进行若干次垃圾收集后再启动一次内存碎片整理
UseG1GC使用Garbage First收集器

3.2参数示例

3.2.1 默认参数
	C:\Users\nero>java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails  -version
	-XX:InitialHeapSize=268001088 -XX:MaxHeapSize=4288017408 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
	java version "1.8.0_241"
	Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
	Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
	Heap
	 PSYoungGen      total 76288K, used 3932K [0x000000076ad00000, 0x0000000770200000, 0x00000007c0000000)
	  eden space 65536K, 6% used [0x000000076ad00000,0x000000076b0d7240,0x000000076ed00000)
	  from space 10752K, 0% used [0x000000076f780000,0x000000076f780000,0x0000000770200000)
	  to   space 10752K, 0% used [0x000000076ed00000,0x000000076ed00000,0x000000076f780000)
	 ParOldGen       total 175104K, used 0K [0x00000006c0600000, 0x00000006cb100000, 0x000000076ad00000)
	  object space 175104K, 0% used [0x00000006c0600000,0x00000006c0600000,0x00000006cb100000)
	 Metaspace       used 2306K, capacity 4480K, committed 4480K, reserved 1056768K
	  class space    used 255K, capacity 384K, committed 384K, reserved 1048576K
	  
	C:\Users\nero>
3.2.2 UseSerialGC
C:\Users\nero>java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC -version
-XX:InitialHeapSize=268001088 -XX:MaxHeapSize=4288017408 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseSerialGC
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
Heap
 def new generation   total 78656K, used 4197K [0x00000006c0600000, 0x00000006c5b50000, 0x0000000715950000)
  eden space 69952K,   6% used [0x00000006c0600000, 0x00000006c0a19618, 0x00000006c4a50000)
  from space 8704K,   0% used [0x00000006c4a50000, 0x00000006c4a50000, 0x00000006c52d0000)
  to   space 8704K,   0% used [0x00000006c52d0000, 0x00000006c52d0000, 0x00000006c5b50000)
 tenured generation   total 174784K, used 0K [0x0000000715950000, 0x0000000720400000, 0x00000007c0000000)
   the space 174784K,   0% used [0x0000000715950000, 0x0000000715950000, 0x0000000715950200, 0x0000000720400000)
 Metaspace       used 2306K, capacity 4480K, committed 4480K, reserved 1056768K
  class space    used 255K, capacity 384K, committed 384K, reserved 1048576K
  
C:\Users\nero>
3.2.3 UseParNewGC
C:\Users\nero>java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseParNewGC -version
Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release
-XX:InitialHeapSize=268001088 -XX:MaxHeapSize=4288017408 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
Heap
 par new generation   total 78656K, used 4197K [0x00000006c0600000, 0x00000006c5b50000, 0x0000000715950000)
  eden space 69952K,   6% used [0x00000006c0600000, 0x00000006c0a19618, 0x00000006c4a50000)
  from space 8704K,   0% used [0x00000006c4a50000, 0x00000006c4a50000, 0x00000006c52d0000)
  to   space 8704K,   0% used [0x00000006c52d0000, 0x00000006c52d0000, 0x00000006c5b50000)
 tenured generation   total 174784K, used 0K [0x0000000715950000, 0x0000000720400000, 0x00000007c0000000)
   the space 174784K,   0% used [0x0000000715950000, 0x0000000715950000, 0x0000000715950200, 0x0000000720400000)
 Metaspace       used 2306K, capacity 4480K, committed 4480K, reserved 1056768K
  class space    used 255K, capacity 384K, committed 384K, reserved 1048576K

C:\Users\nero>
3.2.4 UseConcMarkSweepGC
C:\Users\nero>java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -version
-XX:InitialHeapSize=268001088 -XX:MaxHeapSize=4288017408 -XX:MaxNewSize=1134141440 -XX:MaxTenuringThreshold=6 -XX:OldPLABSize=16 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseConcMarkSweepGC -XX:-UseLargePagesIndividualAllocation -XX:+UseParNewGC
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
Heap
 par new generation   total 78656K, used 4197K [0x00000006c0600000, 0x00000006c5b50000, 0x0000000703f90000)
  eden space 69952K,   6% used [0x00000006c0600000, 0x00000006c0a19618, 0x00000006c4a50000)
  from space 8704K,   0% used [0x00000006c4a50000, 0x00000006c4a50000, 0x00000006c52d0000)
  to   space 8704K,   0% used [0x00000006c52d0000, 0x00000006c52d0000, 0x00000006c5b50000)
 concurrent mark-sweep generation total 174784K, used 0K [0x0000000703f90000, 0x000000070ea40000, 0x00000007c0000000)
 Metaspace       used 2306K, capacity 4480K, committed 4480K, reserved 1056768K
  class space    used 255K, capacity 384K, committed 384K, reserved 1048576K

C:\Users\nero>
3.2.5UseParallelGC
C:\Users\nero>java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseParallelGC -version
-XX:InitialHeapSize=268001088 -XX:MaxHeapSize=4288017408 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
Heap
 PSYoungGen      total 76288K, used 3932K [0x000000076ad00000, 0x0000000770200000, 0x00000007c0000000)
  eden space 65536K, 6% used [0x000000076ad00000,0x000000076b0d7240,0x000000076ed00000)
  from space 10752K, 0% used [0x000000076f780000,0x000000076f780000,0x0000000770200000)
  to   space 10752K, 0% used [0x000000076ed00000,0x000000076ed00000,0x000000076f780000)
 ParOldGen       total 175104K, used 0K [0x00000006c0600000, 0x00000006cb100000, 0x000000076ad00000)
  object space 175104K, 0% used [0x00000006c0600000,0x00000006c0600000,0x00000006cb100000)
 Metaspace       used 2306K, capacity 4480K, committed 4480K, reserved 1056768K
  class space    used 255K, capacity 384K, committed 384K, reserved 1048576K

C:\Users\nero>
3.2.6UseParallelOldGC
C:\Users\nero>java -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseParallelOldGC -version
-XX:InitialHeapSize=268001088 -XX:MaxHeapSize=4288017408 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelOldGC
java version "1.8.0_241"
Java(TM) SE Runtime Environment (build 1.8.0_241-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.241-b07, mixed mode)
Heap
 PSYoungGen      total 76288K, used 3932K [0x000000076ad00000, 0x0000000770200000, 0x00000007c0000000)
  eden space 65536K, 6% used [0x000000076ad00000,0x000000076b0d7240,0x000000076ed00000)
  from space 10752K, 0% used [0x000000076f780000,0x000000076f780000,0x0000000770200000)
  to   space 10752K, 0% used [0x000000076ed00000,0x000000076ed00000,0x000000076f780000)
 ParOldGen       total 175104K, used 0K [0x00000006c0600000, 0x00000006cb100000, 0x000000076ad00000)
  object space 175104K, 0% used [0x00000006c0600000,0x00000006c0600000,0x00000006cb100000)
 Metaspace       used 2306K, capacity 4480K, committed 4480K, reserved 1056768K
  class space    used 255K, capacity 384K, committed 384K, reserved 1048576K

C:\Users\nero>

3.3 其他参数

参数描述示例
-Xms初始堆大小-Xms50m
-Xmx最大堆大小-Xmx50m
-Xmn年轻代大小-Xmn17m

4 规范

https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html
https://docs.oracle.com/javase/specs/jls/se18/html/index.html

### JVM垃圾收集器的工作原理 JVM中的垃圾收集器负责自动管理和释放不再使用的内存资源。这一过程对于维护Java应用程序的性能至关重要[^1]。垃圾收集的主要目标是在不影响应用正常运行的前提下尽可能高效地回收无用对象所占有的空间。 #### 垃圾收集器类型及其特性 多种类型的垃圾收集器存在于现代版本的JVM中,每种都有各自的设计理念来适应特定应用场景下的需求: - **Serial GC**:适用于单核处理器的小规模应用环境,在年轻代采用复制算法,在老年代则使用标记-整理算法。 - **Parallel GC (也称为Throughput Collector)**:专为多CPU系统设计,旨在最大化吞吐量,即完成更多有用工作的比例相对于总执行时间而言。该收集器同样区分新生代与年老代,并分别运用不同的清理策略以达到最佳效果。 - **CMS (Concurrent Mark-Sweep) GC**:专注于降低暂停时间而非整体效率,适合于那些对响应速度敏感的服务端程序。它可以在后台逐步扫描存活对象并清除死亡对象而不必完全停止整个应用程序进程。 - **G1 (Garbage First) GC**:自JDK 7更新版引入以来成为默认选项之一,特别擅长处理具有大量活跃数据的大容量堆配置。G1将整个堆划分为多个固定大小的区域(region),并通过预测哪些地区最有可能包含可回收的空间来进行优先级排序。 - **ZGC 和 Shenandoah GC**:这两种新型低延迟垃圾收集器是从JDK 11开始加入的支持超大型堆(可达数TB级别)的同时具备亚毫秒级别的短暂停滞特性的工具[ZGC][^5]。它们都采用了先进的并发技术使得大部分垃圾回收活动能够在不停止用户线程的情况下发生。 ### 如何选择合适的垃圾收集器? 选择最适合项目需求的垃圾收集器取决于具体的应用场景以及期望达成的目标。如果追求最高的吞吐率,则可能倾向于使用`Parallel GC`; 若更看重快速反应时间和较低的停顿频率,那么像`CMS`, `G1`, 或者最新的`ZGC/Shenandoah`可能是更好的选择。值得注意的是,“最优”的方案并非永恒不变——随着业务逻辑的发展和技术进步,原先选定的最佳实践可能会变得不合适,因此定期审查当前设置总是明智之举[^2]。 ### 性能调优建议 为了使选中的垃圾收集器发挥最大效能,可以通过调整一系列参数来进行精细化控制。这包括但不限于设定初始/最大堆尺寸(-Xms/-Xmx), 新生代占比(-XX:NewRatio), 生存阈值(-XX:+UseAdaptiveSizePolicy,-XX:MaxTenuringThreshold)等。此外,启用详细的日志记录功能可以帮助诊断潜在瓶颈所在之处,从而指导后续改进措施的方向。最终目的是找到一个平衡点,在满足服务等级协议(SLA)关于响应时间和吞吐量的要求之间取得良好折衷。 ```bash java -Xms512m -Xmx4g -XX:+UseG1GC MyApplication ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值