JVM垃圾回收
垃圾回收概述
- 垃圾回收是JVM自动管理内存的一种机制
- 垃圾回收器会自动回收不再使用的对象,释放内存空间
垃圾回收算法
- 标记-清除算法:标记不再使用的对象,清除内存空间
- 复制算法:将存活的对象复制到另一个内存区域,清除原内存空间
- 标记-整理算法:标记不再使用的对象,将存活的对象向一端移动,清除另一端的内存空间
- 分代收集算法:根据对象的生命周期将内存分为不同的代,对不同代采用不同的垃圾回收算法
各垃圾回收器的优缺点
垃圾回收器 | 优点 | 缺点 |
---|---|---|
Serial | 简单高效,线程私有 | 无法利用多核优势,停顿时间过长 |
Parallel | 可以利用多核优势,停顿时间较短 | 内存占用较大,GC时无法同时处理多个CPU |
CMS | 停顿时间短,适用于Web应用等低延迟场景 | 内存碎片化,线程同步开销大,CPU占用高 |
G1 | 可以兼顾吞吐量和延迟,内存占用可控 | 暂停时间不可预测,运行稳定性有待提高 |
ZGC | 停顿时间极短,吞吐量高,内存占用可控 | 目前还处于实验性阶段,不够稳定 |
垃圾回收使用的算法和配置参数
垃圾回收器 | 回收算法 | 关键参数 | 场景 |
---|---|---|---|
Serial | 标记-清除 | -Xms, -Xmx, -Xmn, -XX:NewRatio, -XX:SurvivorRatio | 单核CPU环境,对吞吐量和停顿时间要求不高的场景 |
Parallel | 标记-整理 | -Xms, -Xmx, -Xmn, -XX:NewRatio, -XX:SurvivorRatio, -XX:ParallelGC | 对吞吐量要求高,可以容忍一定停顿时间的场景,比如数据仓库等 |
CMS | 标记-清除 | -Xms, -Xmx, -Xmn, -XX:NewRatio, -XX:SurvivorRatio, -XX:CMSInitiatingOccupancyFraction | 对停顿时间要求较高的低延迟场景,比如Web应用等 |
G1 | 标记-整理+复制 | -Xms, -Xmx, -Xmn, -XX:NewRatio, -XX:G1HeapRegionSize, -XX:G1ReservePercent, -XX:InitiatingHeapOccupancyPercent | 对吞吐量和停顿时间都有要求的场景,可控制内存占用和GC时间段 |
ZGC | 标记-整理+复制 | -Xms, -Xmx, -XX:ConcGCThreads, -XX:ConcGCThreads, -XX:ZUncommitDelay, -XX:ZUncommitDelayMillis | 对停顿时间要求非常高的场景,可以承受一定吞吐量下降的代价,目前还不适用于生产环境的大规模应用 |
关键参数说明
Serial GC:
-XX:+UseSerialGC
-XX:NewRatio: 新生代与老年代大小比例
-XX:SurvivorRatio: Eden区与Survivor区大小比例
-XX:MaxTenuringThreshold: 对象晋升老年代的阈值
Parallel GC:
-XX:+UseParallelGC
-XX:ParallelGCThreads: 设置并行GC的线程数目
-XX:MaxGCPauseMillis: 设置最大GC暂停时间
-XX:GCTimeRatio: 设置吞吐量大小和GC时间比例,例如 -XX:GCTimeRatio=19 表示允许的最大GC时间是19%,即1秒钟中只允许0.19秒的GC时间。
CMS GC:
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction: 设置老年代占用比例,达到这个比例就会启动CMS GC
-XX:+UseCMSInitiatingOccupancyOnly: 设置只使用CMS GC作为老年代的回收器
-XX:+UseParNewGC: 开启并行新生代GC,可以与CMS GC配合使用
G1 GC:
-XX:+UseG1GC
-XX:G1HeapRegionSize: 设置G1中的Region大小,默认值为堆大小的1/2000
-XX:MaxGCPauseMillis: 设置最大GC暂停时间
-XX:InitiatingHeapOccupancyPercent: 设置触发混合GC的堆占用率阈值,即启动混合GC的条件
-XX:G1MixedGCLiveThresholdPercent: 设置存活对象的阈值,即存活对象占Region总容量的百分比,达到这个阈值会触发混合GC
其中 -XX:+ 开头的参数表示开启该功能,-XX:- 表示关闭该功能,-XX: 开头的参数则表示对应的具体配置。需要注意的是,不同版本的JVM可能会有不同的参数名和默认值,具体需要查看对应版本的文档。
关键参数是调整GC行为和性能的关键,需要根据应用程序的特点和运行环境来进行调整,一般建议使用默认值,如果需要进行调整,可以通过实际的测试和观察来进行优化。
各种垃圾回收器的对比
垃圾回收器 | 优点 | 缺点 |
---|---|---|
ZGC | - 非常低的停顿时间,可以在不超过10ms的时间内处理大型堆内存。 - 并发垃圾回收,可以与应用程序并发执行。 - 高并发性和可扩展性,可预测性好。 |
- 不支持压缩和内存碎片整理,可能会导致内存浪费。 - 由于使用复杂的并发算法,可能会导致性能略有下降。 - 需要更多的CPU和内存资源,不适用于小型应用程序。 |
G1 | - 非常灵活和可配置,可以根据应用程序的需求动态调整垃圾回收策略。 - 垃圾回收过程可预测和控制,适用于大型堆内存。 - 支持压缩和内存碎片整理,可以最大限度地利用内存。 - 在Java 9及以上版本中,支持自适应压缩,进一步提高了内存利用率和性能。 |
- 停顿时间相对较长,会对应用程序的性能产生影响。 - 垃圾回收过程复杂,会占用更多的CPU和内存资源。 - 容易导致分代内存碎片化,需要额外的内存管理工作。 |
CMS | - 高并发性,可以与应用程序并发执行垃圾回收操作。 - 停顿时间相对较短,对应用程序性能的影响较小。 - 不会导致分代内存碎片化。 - 适用于需要较高响应性能的应用程序。 |
- 不支持压缩和内存碎片整理,可能会导致内存浪费。 - 由于并发 |
总结
Serial收集器:适用于单核处理器、小型或中小型应用程序。缺点是在进行垃圾回收时应用程序会暂停。
Parallel收集器:适用于多核处理器、中型应用程序。它可以减少暂停时间,但在进行垃圾回收时应用程序仍会暂停。
CMS收集器:适用于需要短暂的停顿时间,响应时间敏感的应用程序。它可以减少垃圾收集时的暂停时间,但可能会出现并发问题。
G1收集器:适用于大型、多核处理器、需要低延迟的应用程序。它可以在不同区域之间动态分配垃圾回收时间,并且能够在应用程序运行时实现并发垃圾回收。
ZGC收集器:适用于需要极低延迟和高吞吐量的大型应用程序。它具有可预测的暂停时间,能够有效利用大内存,并且可以在多个CPU和内存之间动态分配工作负载。