06_G1调优配置

2024-05-05 19:28
文章标签 配置 06 调优 g1

本文主要是介绍06_G1调优配置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本章主要介绍,如果G1默认的一些配置无法满足你的需求,要如何进一步调优。

G1的一般建议

一般建议是使用G1并保持默认设置,如有需要,可以通过使用 -Xmx 来设置最大的Java堆大小,同时也可以通过 -XX:MaxGCPauseMillis来指定不同的暂停时间目标。

G1的默认配置与其他收集器的平衡有所不同。G1在默认配置中的目标既不是追求最大吞吐量,也不是追求最低延迟,而是提供相对较小、统一的暂停时间以获得高吞吐量。然而,G1在堆空间中逐步回收空间和暂停时间控制会给应用线程和空间回收效率带来一些开销。

如果您更看重高吞吐量,则可以通过使用 -XX:MaxGCPauseMillis 放宽暂停时间目标或提供更大的堆。如果延迟是主要考虑因素,则可以修改暂停时间目标。应尽量避免使用类似 -Xmn、-XX:NewRatio 等选项限制年轻代大小,因为年轻代大小是G1控制暂停时间的主要手段。将年轻代大小设置为一个固定值会覆盖并实际上禁用了暂停时间控制。

从其他收集器转向 G1

通常情况下,从其他收集器(尤其是并发标记清除收集器)切换到G1时,首先应删除所有影响垃圾收集的选项,只通过 -Xmx 以及可选的 -Xms 来设置暂停时间目标和总体堆大小。

许多对其他收集器有效的选项在G1中要么根本不起作用,要么甚至会降低吞吐量和满足暂停时间目标的可能性。一个例子就是设置年轻代大小,这样完全阻止了G1调整年轻代大小来满足暂停时间目标。

改善 G1的性能表现

G1旨在在无需指定额外选项的情况下提供良好的整体性能。然而,在某些情况下,默认的启发式算法或其配置可能会导致性能不佳。本节提供了一些诊断和改进这些情况的指南。本指南仅描述了针对给定应用程序,在给定度量标准下,G1提供了哪些可能性来改进垃圾收集器的性能。从案例出发,应用级别的优化可能比尝试调整虚拟机以获得更好性能更为有效,例如通过完全避免一些长生命周期对象所带来的一些问题情况。

为了诊断目的,G1提供了全面的日志记录。一个很好的起点是使用 -Xlog:gc*=debug 选项,然后根据需要细化输出内容。日志提供了关于垃圾收集活动在暂停期间和暂停期间之外的详细概述。其中包括收集类型以及在暂停期间特定阶段所花费的时间。

接下来的小节将探讨一些常见性能问题。

观察FGC

Full GC 通常会耗费大量时间。由于老年代堆内存占用过高而引起的Full GC,在日志中可以通过找到“Pause Full (G1 Compaction Pause)”这些词来检测。而Full GC通常都是由于垃圾回收遭遇了疏散失败(Evacuation Failure)标签表示的先前事件导致。

Full GC发生的原因是因为应用程序分配了太多无法迅速回收的对象。通常情况下,并发标记无法及时完成以启动空间回收阶段。频繁分配大对象可能加剧出现Full GC的概率。由于G1中这些对象的分配方式,它们可能会占用比预期更多的内存。

目标应该是确保并发标记能够按时完成。这可以通过减少老年代中的分配速率,或者给并发标记更多时间来实现。

G1提供了一些选项来更好地处理这种情况:

  • - 可以使用gc+heap=info日志记录来确定Java堆上被巨型对象占用的区域数量。在“Humongous regions:X->Y”这一行中,Y表示被巨型对象占用的区域数量。如果与老年代区域数量相比,这个数字较高,则最佳选项是尝试减少这些对象的数量。可以通过增加区域大小来实现,使用 -XX:G1HeapRegionSize 选项设定区域大小。当前所选的堆区域大小将在日志开头打印出来。
  • - 增加Java堆的大小。通常会增加标记过程完成所需时间。
  • - 通过显式设置 -XX:ConcGCThreads 来增加并发标记线程数。
  • - 强制G1提早开始标记阶段。G1根据先前应用程序行为自动确定初始堆占用百分比(IHOP)阈值。如果应用程序行为发生变化,这些预测可能有误。有两种选择:增加自适应IHOP计算中使用的缓冲区以降低开始空间回收的目标占用率,即修改 -XX:G1ReservePercent;或者通过手动设置 -XX:-G1UseAdaptiveIHOP 和 -XX:InitiatingHeapOccupancyPercent 来禁用IHOP自适应计算。

Full GC除了分配失效之外还有其他原因,通常表明应用程序或某些外部工具导致进行了完整堆收集。如果造成原因是System.gc(),且无法修改应用程序源代码,则可以通过使用 -XX:+ExplicitGCInvokesConcurrent 来缓解Full GC带来的影响,或者通过设置 -XX:+DisableExplicitGC 让虚拟机完全忽略它们;外部工具可能仍然会强制进行Full GC,只能通过不再请求它们来移除这些影响。

巨大对象的碎片

完整的垃圾回收(Full GC)有可能在Java堆内存耗尽之前发生,因为需要找到一组连续的区域。在这种情况下,可以考虑增加堆区域大小,通过使用选项 -XX:G1HeapRegionSize 来减少巨型对象的数量,或者增加堆的大小。在极端情况下,即使可用内存表明有足够的内存空间,G1可能无法为对象分配到足够的连续空间。如果这种情况发生,那么在Full GC无法回收足够的连续空间时会导致虚拟机退出。因此,在这种情况下,除了减少如前所述巨型对象分配的数量或增加堆之外别无选择。

为延迟调优

这部分讨论了改善G1行为的提示,以解决常见的延迟问题,即暂停时间过长的情况。

非常规系统或实时使用

对于每次垃圾回收暂停,gc+cpu=info日志输出中都包含一行,其中包括来自操作系统的信息,详细说明了在暂停期间花费的时间。例如,输出中的一行可能是:User=0.19s Sys=0.00s Real=0.01s。

用户时间是在虚拟机代码中花费的时间,系统时间是在操作系统中花费的时间,而实际时间则是在暂停期间经过的绝对时间量。如果系统时间相对较高,则大多数情况下环境是造成延迟的原因。

导致系统时间过高的常见已知问题包括:

  • - 虚拟机分配或返还操作系统内存可能会导致不必要的延迟。通过使用选项 -Xms 和 -Xmx 将最小堆大小和最大堆大小设置为相同值,并使用 -XX:+AlwaysPreTouch 预分配所有内存,将这一工作移到虚拟机启动阶段以避免这些延迟。
  • - 特别是在Linux环境下,透明大页(THP)功能将小页面合并为大页面,往往会使随机进程停滞,而不仅仅只是在暂停期间。由于虚拟机分配和维护了大量内存,因此出现虚拟机长时间停滞的风险比通常更高。请参阅您操作系统的文档以了解如何禁用透明大页功能。
  • - 由于某些后台任务不时占用写入日志所用硬盘的所有I/O带宽,日志输出可能会暂时停顿一段时间。考虑使用独立硬盘或其他存储设备来存储日志文件,例如基于内存的文件系统,从而避免这种情况。

另一个需要注意的情况是实际时间远远大于其他两者之和,这可能表明虚拟机未能获得足够CPU时间,在可能过载的计算机上发生了长时间停滞。

引用对象处理花费的时间太长

在“引用处理”阶段会显示关于引用对象处理时间的信息。在引用处理阶段,G1根据特定类型的引用对象的需求更新引用对象的引用。默认情况下,G1尝试使用以下启发式方法并行化引用处理的子阶段:对于每个 -XX:ReferencesPerThread 个引用对象,启动一个线程,并受 -XX:ParallelGCThreads 指定线程数的限制。可以通过将 -XX:ReferencesPerThread 设置为 0 来禁用此启发式方法,默认情况下使用所有可用线程,或通过 -XX:-ParallelRefProcEnabled 完全禁用并行化。

年轻代收集耗费太多时间

年轻代的普通收集以及一般情况下任何年轻代收集的时间大致与年轻代的大小成正比,或者更具体地说,与需要被复制的收集集合中的存活对象数量成正比。如果疏散集合阶段花费的时间过长,特别是对象复制子阶段,则可以通过减小 -XX:G1NewSizePercent 来解决。这会减小年轻代的最小大小,有望缩短暂停时间。

另一个关于年轻代大小的问题可能出现在应用程序性能以及尤其是在收集后存活对象数量突然改变时。这可能导致垃圾回收暂停时间出现波动。通过使用 -XX:G1MaxNewSizePercent 减小最大年轻代大小可能会有所帮助。这样可以限制年轻代的最大大小,从而减少暂停期间需要处理的对象数量。

混合收集花费的时间太长

混合年轻代收集用于回收老年代的空间。混合收集的收集集合包含年轻代和老年代区域。您可以通过启用 gc+ergo+cset=debug 日志输出来获取有关疏散年轻代或老年代区域对暂停时间贡献的信息。寻找以下日志消息:

Added young regions to CSet.[...] predicted eden time:4.86ms,predicted base time:9.98ms,target pause time:200.00ms,[...]

Eden 时间和 base 时间一起给出了预测的年轻代区域时间,即 G1 预计疏散年轻代所需的时间。

预测旧区域时间的日志消息如下所示:

Finish choosing collection set old regions.[...] predicted initial time:147.70ms,predicted optional time:15.45ms,[...]

在这里,预测初始时间表示预测的旧区域时间,即 G1 预计疏散最小集合的老年代区域所需的时间。

如果预测的年轻代区域时间太长,请参阅“只有年轻代收集在年轻代阶段花费太长时间”部分进行调整。否则,为了减少老年代区域对暂停时间的贡献,G1 提供了三个选项:

  • 通过增加 -XX:G1MixedGCCountTarget 来将老年代区域回收分布到更多垃圾回收中。
  • 通过使用 -XX:G1MixedGCLiveThresholdPercent 将需要大量时间来回收的区域排除在候选回收集合之外,以避免将它们放入候选回收集合。在许多情况下,占用率高的区域需要大量时间来进行回收。
  • 提早停止老年代空间回收,这样 G1 将不会回收那么多占用率高的区域。在这种情况下,增加 -XX:G1HeapWastePercent。

请注意,最后两个选项会减少候选回收集合中可进行当前空间回收阶段空间回收数量。这可能意味着 G1 可能无法为持续操作回收足够老年代空间。但是,稍后的空间回收阶段可能会进行垃圾回首处理这些空间。

连续出现垃圾回收

G1默认的MMU设置允许连续进行垃圾回收。-XX:GCPauseIntervalMillis 的默认值略高于 -XX:MaxGCPauseMillis。如果观察到连续进行垃圾回收导致应用无法进展,可以增加 -XX:GCPauseIntervalMillis 的值至一个可接受的水平。这样,G1 将尝试减少垃圾回收的频率。

高合并堆根和扫描堆根时间

减少这两个阶段的一种方法是通过调整组合记忆集中记忆集条目的数量来减少。使用 -XX:G1HeapRegionSize 选项调整堆区域的大小可以减少跨区域引用大小的记忆集。更大的区域往往具有较少的跨区域引用,因此在处理它们时所花费的工作量减少,尽管与此同时,更大的区域可能意味着每个区域需要疏散更多存活对象,从而增加其他阶段的时间。

如果垃圾回收过程中有相当多的时间(即超过60%)花费在这两个阶段上,一个选择是通过减小 -XX:GCCardSizeInBytes 选项的值来降低记忆集条目的粒度:更细粒度会减少查找引用所需的工作量,但会增加一些额外内存消耗。

在应用程序分配大对象时,结合出现无端高 Scan Heap Roots 时间可能是由于一种优化引起,该优化尝试通过批量处理来减少并发记忆集更新工作。如果此类批处理是在垃圾回收之前创建的应用程序执行,则可能对 Merge Heap Roots 时间产生负面影响。使用 -XX:-ReduceInitialCardMarks 可以禁用此优化,从而潜在避免出现这种情况。

为吞吐量调优

G1的默认策略试图在吞吐量和延迟之间取得平衡;然而,在某些情况下,更高的吞吐量是可取的。除了按照前面部分所描述的减少总暂停时间之外,还可以减少暂停的频率。主要思路是使用 -XX:MaxGCPauseMillis 增加最大暂停时间。代际大小的启发式方式将自动调整年轻代的大小,这直接决定了暂停的频率。如果这不会产生预期行为,尤其是在空间回收阶段,可以使用 -XX:G1NewSizePercent 来增加最小年轻代大小来强制 G1 这样做。

在某些情况下,-XX:G1MaxNewSizePercent,即允许的年轻代最大大小,可能会通过限制年轻代大小来限制吞吐量。可以通过查看gc+heap=info日志记录中区域汇总输出来进行诊断。在这种情况下,Eden 区域和 Survivor 区域的合并百分比接近于总区域数的 -XX:G1MaxNewSizePercent 百分比。此时可以考虑增加 -XX:G1MaxNewSizePercent。

另一个提高吞吐量的选择是减少并发工作量。特别是,并发记忆集更新通常需要大量 CPU 资源。可以使用 -XX:G1RSetUpdatingPauseTimePercent 选项将工作从并发操作转移到垃圾回收暂停中。

增加此值可能会减少同时调度给应用程序进行细化工作,反之亦然;减少此值可能会增加同时与应用程序进行细化工作的量。

启用 gc+phases=debug 日志记录时,在 Merge Heap Roots 阶段的 Log Buffers 部分跟踪垃圾回收暂停中的细化工作。

通过使用 -XX:+UseLargePages 启用大页功能也可能提高吞吐量。请参考操作系统文档以了解如何设置大页。

您可以通过禁用堆调整工作来尽量减少它;将选项 -Xms 和 -Xmx 设置为相同值。此外,您还可以使用 -XX:+AlwaysPreTouch 将操作系统工作移到虚拟内存上以缩短虚拟机启动时间。这些措施特别有助于使暂停时间更加稳定。

为堆大小调优

与其他收集器一样,G1旨在调整堆大小,使得垃圾回收所花费的时间低于由 -XX:GCTimeRatio 选项确定的比率。调整此选项以使G1满足您的需求。

可调的默认值

本节介绍本主题中引入的默认值和有关命令行选项的一些描述和附加信息。

Option and Default ValueDescription

-XX:+ReduceInitialCardMarks

This batches together concurrent remembered set update (refinement) work for initial object allocations.

-XX:+ParallelRefProcEnabled

-XX:ReferencesPerThread=1000

-XX:ReferencesPerThread determines the degree of parallelization: for every N Reference Objects one thread will participate in the sub-phases of Reference Processing, limited by -XX:ParallelGCThreads. A value of 0 indicates that the maximum number of threads as indicated by the value of -XX:ParallelGCThreads will always be used. 

This determines whether processing of java.lang.Ref.* instances should be done in parallel by multiple threads.

-XX:G1RSetUpdatingPauseTimePercent=10 

The concurrent remembered set update (refinement) work can be controlled with this option. Refinement tries to schedule work concurrently so that at most -XX:G1RSetUpdatingPauseTimePercent percent of the maximum pause time goal is spent in the garbage collection pause in the Update RS phase, processing remaining work.

-XX:G1SummarizeRSetStatsPeriod=0 

This is the period in a number of GCs that G1 generates remembered set summary reports. Set this to zero to disable. Generating remembered set summary reports is a costly operation, so it should be used only if necessary, and with a reasonably high value. Use gc+remset=trace to print anything.

-XX:GCTimeRatio=12 

This is the divisor for the target ratio of time that should be spent in garbage collection as opposed to the application. The actual formula for determining the target fraction of time that can be spent in garbage collection before increasing the heap is 1 / (1 + GCTimeRatio). This default value results in a target with about 8% of the time to be spent in garbage collection.

-XX:G1PeriodicGCInterval=0

The interval in ms to check whether G1 should trigger a periodic garbage collection. Set to zero to disable.

-XX:+G1PeriodicGCInvokesConcurrent

If set, periodic garbage collections trigger a concurrent marking or continue the existing collection cycle, otherwise trigger a Full GC.

-XX:G1PeriodicGCSystemLoadThreshold=0.0Threshold for the current system load as returned by the hosts getloadavg() call to determine whether a periodic garbage collection should be triggered. A current system load higher than this value prevents periodic garbage collections. A value of zero indicates that this threshold check is disabled.

注意: < ergo > 意味着实际值是根据环境的人机工程学确定的。 

这篇关于06_G1调优配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/962483

相关文章

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

关于Maven中pom.xml文件配置详解

《关于Maven中pom.xml文件配置详解》pom.xml是Maven项目的核心配置文件,它描述了项目的结构、依赖关系、构建配置等信息,通过合理配置pom.xml,可以提高项目的可维护性和构建效率... 目录1. POM文件的基本结构1.1 项目基本信息2. 项目属性2.1 引用属性3. 项目依赖4. 构

龙蜥操作系统Anolis OS-23.x安装配置图解教程(保姆级)

《龙蜥操作系统AnolisOS-23.x安装配置图解教程(保姆级)》:本文主要介绍了安装和配置AnolisOS23.2系统,包括分区、软件选择、设置root密码、网络配置、主机名设置和禁用SELinux的步骤,详细内容请阅读本文,希望能对你有所帮助... ‌AnolisOS‌是由阿里云推出的开源操作系统,旨

mysql-8.0.30压缩包版安装和配置MySQL环境过程

《mysql-8.0.30压缩包版安装和配置MySQL环境过程》该文章介绍了如何在Windows系统中下载、安装和配置MySQL数据库,包括下载地址、解压文件、创建和配置my.ini文件、设置环境变量... 目录压缩包安装配置下载配置环境变量下载和初始化总结压缩包安装配置下载下载地址:https://d

gradle安装和环境配置全过程

《gradle安装和环境配置全过程》本文介绍了如何安装和配置Gradle环境,包括下载Gradle、配置环境变量、测试Gradle以及在IntelliJIDEA中配置Gradle... 目录gradle安装和环境配置1 下载GRADLE2 环境变量配置3 测试gradle4 设置gradle初始化文件5 i

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to