`

【Java 8 GC 调优】并行GC

    博客分类:
  • Java
 
阅读更多

并行GC,也称为 吞吐量GC,是与 串行GC 类似的 分代GC。其主要区别在于,用多个线程加快垃圾收集速度。
可通过命令行选项 -XX:+UseParallelGC 启用 并行GC。默认情况下,使用此选项后,Minor 和 Major GC 都是并行执行,以进一步减少垃圾收集的开销。
 

在具有超过8个硬件线程的机器上,并行GC 会使用固定占比的数量作为GC线程数。
硬件线程数较大时,该占比为 5/8 。硬件线程数小于8时,GC线程数就是硬件线程数。在特定的平台上,该占比会降到 5/16 。可通过命令行选项指定 GC 线程数(稍后介绍)。
在单处理器机器上,因为并行执行(如,同步)的开销,并行GC 的表现不如 串行GC。
但对于中大型堆的应用程序来说,当运行在双处理器机器上时,并行GC 的性能通常会比 串行GC 稍好一些。有2个以上处理器时,并行GC 的表现会更好。
 

GC 线程数量 可通过命令行选项 -XX:ParallelGCThreads=<N> 来控制。
在已通过命令行显式设置堆大小的情况下,堆大小对良好性能的影响对 并行GC 和 串行GC 是一样的。但是启用 并行GC 应该会缩短暂停时间。
 

老年代碎片化

因为 多个GC线程 同时参与到 Minor GC 中,所以可能会在 “从 新生代 提升到 老年代” 的过程中产生一些碎片。每个 GC 线程都会在 Minor GC 中预留一部分老年代的空间用于“提升”操作。而这个划分 “提升缓冲区” 的操作会产生碎片。
减少 GC 线程数量 和 增大老年代容量 可以降低此“碎片化效果”。

 

“代” 划分

如前所述,并行GC 中“代”的划分方式不同。如下图所示:

 

并行GC Ergonomics

在服务器类机器上,JVM 默认选择 并行GC。此外,并行GC 使用了一种自动调整的方法,它允许你指定特定的行为,而不是“代”容量或其它低级的细节调整。你可以指定 GC 暂停时间的最大值、吞吐量、内存占用(堆大小)。

 

3个 目标

GC 暂停时间最大值

可通过命令行选项 -XX:MaxGCPauseMillis=<N> 指定该最大值。
它会被解释为对GC的提示:暂停时间不能超过 <N> 秒。默认情况下没有最大暂停时间目标。如果指定了暂停时间目标,那么GC会调整 堆大小 及 其它相关参数,以尝试让暂停时间小于指定的值。
这些调整可能会降低应用程序的总吞吐量,而且并不总是能满足暂停时间目标。

 

吞吐量

吞吐量目标是根据 GC所花费时间 与 GC之外所花费时间(称为“应用程序时间”)来衡量的。
应用程序时间占比高就是吞吐量高。
该目标是通过命令行选项 -XX:GCTimeRatio=<N> 来指定的。它表示 GC 时间占总时间的 1/(1+<N>)
例,-XX:GCTimeRatio=19 设置的目标为 GC 时间占总时间的 1/20。默认值为 99,即 GC 时间占总时间的 1% 。

 

内存占用(Footprint)

可通过选项 -Xmx<N> 指定 堆的最大内存占用。此外,GC 还有一个隐含的目标:在满足其它目标的情况下,使堆尽可能小。

 

目标优先级

这些目标的优先级顺序如下:

  1. 最长暂停时间
  2. 吞吐量
  3. 最小内存占用

首先需满足最长暂停时间目标。只有满足它后,才去实现吞吐量目标。同样的,只有前两个目标实现后,才会考虑内存占用的目标。

 

调整“代”大小

GC 保留的统计信息(如 平均暂停时间)在每次收集结束时都会被更新。然后检查是否满足上述目标,如有必要,就会调整“代”的大小。也有例外情况,统计信息更新 和 “代”大小调整策略 会忽略 显式GC操作(如,调用 System.gc() )。
 

GC 会用“代”大小的固定百分比来增大或缩小“代”,使得它满足期望的规模。增大与缩小的比例不同。
默认情况下,增大的比例为 20%,缩小的比例为 5% 。
可通过命令行选项 -XX:YoungGenerationSizeIncrement=<Y>-XX:TenuredGenerationSizeIncrement=<Y> 分别调整 新生代 和 老年代 的增长比例。
-XX:AdaptiveSizeDecrementScaleFactor=<D> 可调整缩小的比例。如果增大的比例为 X%,那么缩小的比例为 (X/D)%
 

如果在程序启动时,GC决定增大“代”,那么它会为“增大比例”加一个补充量。此补充量并不是长期有效的,它会随着 GC 次数的增加而衰减。这个补充量的目的是为了提高启动性能。
“缩小比例”没有补充量。
 

如果 最长暂停时间 不达标,则一次只缩小一个“代”的容量。
如果两“代”的暂停时间都未达标,则会先缩小暂停时间更长的“代”。
 

如果 吞吐量 不达标,则两“代”容量都会增大。每“代”按照各自占GC总时间的比例增大。
例如,如果新生代的GC时间占总GC时间的25%,且新生代的完整“增大比例”为20%,则此次新生代容量会被增大5% (25% * 20% = 5%)。

 

默认堆大小

除非通过命令行指定了堆的初始容量和最大容量,否则将根据机器上的内存量计算。
 

Client JVM 中 堆大小的 默认初始值和最大值

如果物理内存不超过 192MB,则默认最大堆容量为物理内存的一半。否则默认堆容量为物理内存的 1/4 。
 

例如,如果计算机物理内存为128MB,则最大堆容量为64MB;如果物理内存大于等于1GB,则最大堆容量为256MB。
 

除非你的程序创建了足够多的对象,否则 JVM 实际上不会使用到最大堆容量。
JVM 在初始化时会分配小得多的内存,称为初始堆大小。该容量至少是 8MB,或者是物理内存的 1/64 。
 

新生代的默认最大容量是总堆的 1/3 。

 

Server JVM 中 堆大小的 默认初始值和最大值

Server JVM 中 堆大小的默认初始值和最大值 与 Client JVM 类似,只是默认值可能会更高。
在 32位 JVM 上,如果物理内存大于等于4GB,那么默认最大堆容量可以高达 1GB。
在 64位 JVM 上,如果物理内存大于等于128GB,那么默认最大堆容量可以高达 32GB。
你始终可以直接指定更高或更低的初始堆容量和最大堆容量。见下一节。

 

指定 堆的 初始容量 与 最大容量

可以通过 -Xms 和 -Xmx 分别指定堆的初始容量与最大容量。
如果你知道程序需要多大的堆才能正常工作,可以为 -Xms 和 -Xmx 设置相同的值。
如果不指定相同的值,则 JVM 会从初始堆大小开始增大堆,直到找到堆容量和性能之间的平衡。
 

其它参数与选项会影响这些默认值。如需验证这些默认值,可以用 -XX:+PrintFlagsFinal,并在输出中查找 MaxHeapSize 。
如,在 Linux 或 Solaris 中,你可以参照以下命令运行 java:

java -XX:+PrintFlagsFinal  -version | grep MaxHeapSize

 

GC 时间过长 与 OutOfMemoryError

如果垃圾收集耗时过长,并行GC 会抛出异常 OutOfMemoryError。
如果超过 98% 的时间用于垃圾收集,而恢复的堆空间不到 2%,那么会抛出 OutOfMemoryError。
 

此特性旨在防止应用程序运行了很长时间,但由于堆太小而几乎没有进展
如有必要,可通过命令行禁用此特性 -XX:-UseGCOverheadLimit

 

测量

并行GC 的详细输出与 串行GC 基本相同。

 

  • 大小: 7.4 KB
分享到:
评论

相关推荐

    JVM_GC调优

    ### JVM_GC调优详解 #### 一、JVM体系结构概览 Java虚拟机(JVM)作为Java程序的运行环境,其内部结构复杂且高效。为了更好地理解JVM_GC调优,我们首先来了解一下JVM的基本组成部分。 1. **类装载器子系统(Class ...

    Java_GC垃圾回收调优指南

    ### Java GC垃圾回收调优指南 #### 概述 在Java开发过程中,垃圾回收(Garbage Collection, GC)是管理内存资源的关键技术之一。...通过上述指南,希望能帮助开发者更好地掌握GC调优技巧,提高应用程序的整体性能。

    Java服务GC参数调优案例1

    Java服务GC参数调优案例1 Java服务GC参数调优案例的标题“Java服务GC参数调优案例1”和描述“背景以及遇到的问题我们的Java HTTP服务属于OLTP类型,对成功率和响应时间的要求比较高,在生产环境中出现偶现的成功率...

    java gc调优

    然而,GC调优是每个Java开发者都需要面对的挑战,因为合适的GC配置可以显著提高应用的性能和稳定性。以下是对“java gc调优”这一主题的深入探讨。 首先,理解JVM内存结构是GC调优的基础。JVM内存主要分为堆内存...

    JVM体系结构与GC调优

    总的来说,JVM体系结构和GC调优是Java开发者的必备技能。通过深入理解这些概念和技术,我们可以有效地提升Java应用的性能,降低系统资源消耗,从而提供更好的用户体验。这个PPT无疑是学习和掌握这些知识的好资源。

    java内存参数调优技巧

    Java内存参数调优是优化Java应用程序性能的关键环节,特别是对于大型和高负载的应用,合理的内存配置可以有效地降低垃圾收集(Garbage Collection, GC)带来的压力,提高应用的响应速度和系统吞吐量。以下是一些关于...

    用于测试jvm gc调优-share-jvm-gc.zip

    在Java应用程序中,尤其是对于大型系统或高并发环境,进行JVM GC调优是提升性能、减少系统停顿时间的关键步骤。"用于测试jvm gc调优-share-jvm-gc.zip"这个压缩包文件很可能包含了一些工具、脚本或教程,用于帮助...

    gc调优,和jvm调优,特别详细,这是本人花人民币买的

    GC调优主要是对JVM的垃圾回收机制进行调整,以确保内存的有效利用和避免系统出现长时间的暂停。垃圾回收是JVM自动管理内存的过程,其目标是回收不再使用的对象所占用的内存空间。主要涉及以下几个方面: 1. **垃圾...

    jvm-full-gc调优-jvm-full-gc.zip

    本资料"jvm-full-gc调优-jvm-full-gc.zip"显然是针对如何减少和优化JVM的Full GC进行深入探讨的。以下将详细介绍JVM Full GC的相关知识点。 1. **理解JVM内存结构**:Java内存主要分为堆内存(Heap)和非堆内存...

    Java-JVM调优总结

    - **GC 相关参数**:如 `-XX:+UseParallelGC` 使用并行收集器,`-XX:+UseConcMarkSweepGC` 使用 CMS 收集器等。 #### 三、JVM 性能监控与分析工具 1. **VisualVM**:集成多种监控功能的可视化工具,可用于查看 ...

    JVM、GC详解及调优_jvm_JVM、GC详解及调优_

    3. **并行与并发设置**:调整并行GC线程数和并发GC策略,优化性能。 4. **对象存活率预估**:通过调整Survivor区比例,减少Full GC的发生。 5. **内存分配策略**:如使用CMS或G1等高级GC算法,降低STW影响。 此外,...

    Java GC的过程

    六、GC调优 调优GC主要是为了平衡吞吐量和响应时间。可以通过调整以下参数实现: - `-Xms` 和 `-Xmx`:设置堆的最小和最大大小。 - `-XX:NewRatio`:年轻代与老年代的比例。 - `-XX:SurvivorRatio`:新生代中Eden区...

    java性能调优的基本知识.pdf

    选择合适的垃圾收集器(如串行、并行、CMS或G1)并调整相关参数(如新生代和老年代大小),可以帮助优化Java堆的使用,减少GC暂停时间,从而提高应用程序的响应速度。 总之,Java性能调优是一个复杂且细致的过程,...

    JVM、GC详解及调优

    6. **并行与并发**:调整并行GC线程数,合理利用多核CPU资源,同时考虑与应用线程的协同工作。 总结,理解和掌握JVM的工作原理以及GC机制,对于优化Java应用性能至关重要。通过细致的调优,可以有效减少垃圾收集的...

    Tomcat中Java垃圾收集调优[文].pdf

    以下是对Tomcat中Java垃圾收集调优的详细说明: 首先,我们需要了解JVM内存的划分。JVM根据对象的生命周期将其划分为三个主要区域: 1. **Young Generation(年轻代)**:这是对象初次被创建的地方,包括Eden区和...

    java -jvm 内存分配和jvm调优

    4. 使用并行或并发GC:-XX:+UseParallelGC或-XX:+UseConcMarkSweepGC可以选择不同的垃圾收集器,根据应用特点选择合适的策略。 5. CMS收集器设置:对于响应时间敏感的应用,可以使用CMS收集器,通过-XX:+...

Global site tag (gtag.js) - Google Analytics