当前位置:Java -> Shenandoah GC 调优
Shenandoah GC 旨在通过与应用程序线程并发执行垃圾回收来减少Java应用程序的暂停时间。Shenandoah创新的核心是基于区域的内存管理。堆被划分为区域,使得垃圾回收可以独立地在这些区域上进行。这不仅有助于实现高效的并行处理,而且有助于实现低延迟目标。在本文中,我们将探讨特定于增强性能的Shenandoah GC的调优技术。如果你想了解更多基础知识,你可以观看在JAX London会议上的这个垃圾回收调优讲座。
确保你的Java版本支持Shenandoah GC。Shenandoah从版本11开始可在OpenJDK中使用。你也可以使用商业JDK发行版,比如Oracle JDK或AdoptOpenJDK。使用以下JVM参数启用Shenandoah GC来启动你的Java应用程序:
-XX:+UseShenandoahGC
如果你的应用程序具有以下要求之一,你可以考虑使用Shenandoah GC:
Shenandoah GC是应用程序的理想选择,它需要始终保持低暂停时间以保持最佳用户体验。这包括金融系统、在线游戏平台和实时通信应用等场景。
在具有大量内存占用的应用程序中,Shenandoah GC通过在垃圾回收期间最大程度地减少暂停时间而表现出色。此类应用程序的示例包括大数据处理系统、内存数据库和具有广泛数据集的企业级系统。
在不可预测和持续暂停不可接受的情况下,保持可预测的响应时间至关重要,Shenandoah GC在这种情况下非常有价值。这对于交互式Web应用程序尤为相关,用户的交互应该立即得到响应。
适用于经历波动工作负载的应用程序,Shenandoah GC可以适应动态的垃圾回收需求。这包括可伸缩的Web服务和全天候用户活动的应用程序。
在具有高度并发性的多线程应用程序中,传统的垃圾收集器可能难以跟上,而Shenandoah GC提供了一种有效的解决方案。这对于并发数据处理系统和并行计算应用程序尤为相关。
在本节中,让我们回顾一下你可以为你的应用程序配置的重要Shenandoah GC调优参数。
-XX:+AlwaysPreTouch
-XX:+AlwaysPreTouch
是一个JVM参数,它确保提前将堆页面提交到内存。启用该选项(-XX:+AlwaysPreTouch
)可确保内存提前提交,最大程度减少应用程序执行期间的中断。
-Xms
和-Xmx
-Xms
设置Java虚拟机(JVM)启动时的初始堆大小,-Xmx
设置JVM可以使用的最大堆大小。将这两个值设置为相同的值可以确保固定且不可调整的堆大小。这种配置可以减少与堆管理相关的突然中断,为你的应用程序提供稳定和可预测的内存使用情况。你可以参考这篇文章,了解将初始和最大堆大小设置为相同值的详细好处。
-XX:+UseLargePages
和-XX:+UseTransparentHugePages
利用大页面可以显著提高性能,尤其是在大堆上。有两个选项可以启用大页面:
-XX:+UseLargePages
:在Linux或Windows上(具有适当权限)激活对更大内存页面的支持。-XX:+UseTransparentHugePages
:启用对大页面的透明支持。建议调整系统设置,特别是/sys/kernel/mm/transparent_hugepage/enabled和/sys/kernel/mm/transparent_hugepage/defrag,选择“madvise”。当使用此选项与AlwaysPreTouch一起使用时,系统将在启动时提前处理碎片化成本。-XX:+UseNUMA
NUMA(非一致性内存访问)是一种计算机内存设计,为每个处理器提供单独的内存访问,从而增强了多插槽系统上的性能。可以通过传递JVM参数-XX:+UseNUMA
来启用NUMA。对于Shenandoah GC,特别是在多插槽主机上,建议使用此参数。与AlwaysPreTouch结合使用,此选项可以提供与默认配置相比更好的整体性能。
-XX:-UseBiasedLocking
对于对延迟敏感的应用程序,可以通过使用JVM参数-XX:-UseBiasedLocking
关闭偏向锁定来提高性能。这个选项很有用,因为它减少了无竞争(偏向)锁定,从而减少了应用程序执行中潜在的延迟。
Shenandoah GC的性能由其启动的模式控制。你可以通过-XX:ShenandoahGCMode=<name>
JVM参数选择Shenandoah GC模式。以下是可用的Shenandoah模式:
模式 | 描述 |
normal/satb (产品, 默认) | 默认模式与快照始于开头(SATB)标记的并发垃圾回收类似。类似于G1,它截取写操作并通过“前置”对象标记。 |
iu (实验性) | 在这种实验性模式中,Shenandoah 运行具有增量更新(IU)标记的并发垃圾回收。与SATB 不同,IU 截取写操作并通过“新”对象标记,可能使标记不那么保守,特别是在访问弱引用周围。 |
被动(诊断性) | 诊断模式运行暂停世界垃圾回收。主要用于功能测试,也可以有助于确定与垃圾回收屏障相关的性能异常或确定应用程序中的实际活跃数据大小。 |
选择了 Shenandoah GC 运行方式(模式)后,下一个关键因素是决定何时开始清理(GC 循环)以及清除内存的哪些部分(疏散)。这些决定由启发式处理,您可以使用 -XX:ShenandoahGCHeuristics=<name>
设置选择合适的启发式。某些启发式可以通过额外设置进行调整,以更好地满足您的需求。让我们看看可用的启发式:
启发式 | 描述和配置参数 |
1. 自适应(默认) | 观察先前的 GC 循环并开始下一个循环以在堆耗尽之前完成。 - “学习” 收集的初始阈值 (`ShenandoahInitFreeThreshold=#`). - 触发无条件启动 GC 循环的空闲空间阈值 (`ShenandoahMinFreeThreshold=#`). - 为分配峰值保留堆 (`ShenandoahAllocSpikeFactor=#`). - 设置分区收集的垃圾百分比 (`ShenandoahGarbageThreshold=#`). |
2. 静态(先前称为动态) | 根据堆占用触发 GC 循环。 - 设置触发 GC 循环的空闲堆百分比 (`ShenandoahMinFreeThreshold=#`). - 设置分区收集的垃圾百分比 (`ShenandoahGarbageThreshold=#`). |
3. 紧凑(先前称为连续) | 持续运行,直接在上一个循环完成后开始下一个循环。 - 减少用于应用程序空间的并发 GC 线程 (`ConcGCThreads=#`). - 设置自上次 GC 循环以来分配的内存百分比 (`ShenandoahAllocationThreshold=#`). |
4. 激进(诊断性) | 完全激活,直接在上一个循环完成后开始新循环,并疏散所有活跃对象。没有特定的配置参数。主要用于具有显著性能开销的功能测试。 |
Shenandoah,像其他智能垃圾回收器一样,需要更快地清理垃圾,以防止应用程序创建新对象的速度超过它的速度。但是,如果应用程序创建的对象比 Shenandoah 能够跟上的更多,Shenandoah 有一个处理这种情况的备用计划,顺序如下。
-XX:+ShenandoahPacing
,默认启用)当 Shenandoah GC 运行时,它知道需要执行多少 GC 工作以及应用程序可用多少空闲空间。节奏控制器会尝试在 GC 进度不够快时阻塞应用程序线程。在正常情况下,GC 的收集速度比应用程序的分配速度快,因此节奏控制器自然不会阻塞。请注意,节奏控制引入了在通常的分析工具中看不到的本地每线程延迟。这就是为什么停顿不是无限的,而是由 -XX:ShenandoahPacingMaxDelay=#ms
限制的。在最大延迟到期后,分配将无论如何发生。大部分时候,轻微的分配峰值都被节奏控制吸收。当分配压力非常大时,节奏控制将无法应对,问题将移至下一个步骤。由节奏控制引起的延迟将是 <10 ms。
-XX:+ShenandoahDegeneratedGC
,默认启用)如果应用程序遇到分配失败,那么Shenandoah将会进入一个停止应用程序的全局暂停,继续暂停期间的循环。退化GC会在停止世界的情况下继续进行进行中的“并发”循环。在许多情况下,分配失败发生在已经完成了大量GC工作之后,只需要完成一小部分GC工作。这就是为什么STW暂停通常不会很长。这将在GC日志中报告为GC暂停,连同所有通常的监视和心跳线程:事实上,诱发STW暂停的原因之一就是为了使并发模式失败更清晰可观察。如果GC周期开始太晚或者发生了非常重要的分配高峰,就可能发生退化GC。退化周期可能比并发周期更快,因为它不会与应用程序竞争资源,并且不会使用-XX:ConcGCThreads
来调整线程池大小。退化GC引起的延迟将会<100 ms,但根据退化点的不同可能会更高。
如果没有任何帮助,例如,当退化GC没有释放足够的内存时,将发生完全GC周期并将堆紧缩到最大。某些场景,比如与实现性能错误和忽视相结合导致堆异常碎片化,只能通过完全GC来修复。这种最后的GC保证了应用程序不会因为至少还有一些可用内存而发生OutOfMemoryError
。完全GC引起的延迟会大于100 ms,但在非常占用的堆上可能会更高。
通过分析GC日志来研究Shenandoah GC的性能特性是最好的方法。GC日志包含有关垃圾回收事件、内存使用情况和其他相关指标的详细信息。有几种工具可用于分析GC日志,如GCeasy、IBM GC & Memory visualizer、HP Jmeter和Google Garbage Cat。通过使用这些工具,您可以可视化内存分配模式,识别潜在瓶颈,并评估垃圾回收的效率。这样可以在对Shenandoah GC进行微调以获得最佳性能时做出明智的决策。
在Java垃圾回收的动态环境中,Shenandoah提供了低延迟性能和高效内存管理之间的平衡。借助其多功能模式、启发式和主动机制(如节奏和退化GC),Shenandoah为开发人员提供了一个工具,可根据其应用程序的独特需求微调垃圾回收。
推荐阅读: 国企实习信息汇总
本文链接: Shenandoah GC 调优