`
bit1129
  • 浏览: 1069766 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

【JVM四】老年代垃圾回收:吞吐量垃圾收集器(Throughput GC)

    博客分类:
  • JVM
 
阅读更多

吞吐量与用户线程暂停时间

 

衡量垃圾回收算法优劣的指标有两个:

  • 吞吐量越高,则算法越好
  • 暂停时间越短,则算法越好

首先说明吞吐量和暂停时间的含义。

 

垃圾回收时,JVM会启动几个特定的GC线程来完成垃圾回收的任务,这些GC线程与应用的用户线程产生竞争关系,共同竞争处理器资源以及CPU的执行时间。GC线程不会对用户带来的任何价值,因此,好的GC应该占用资源少,执行快,在不显著影响用户线程的情况下,迅速完成垃圾回收任务。

 

吞吐量是针对用户线程而言的,具体指的是在一个给定的时间段内,用户线程运行的时间所占的百分比(在这段时间内,GC运行也要占用CPU的运行时间)。比如,吞吐量99/100表示平均100秒的时间段内,有99秒在运行用户程序,而有1秒在运行GC线程,

 

暂停的含义是指,在一个给定的时间段内,应用线程由于GC而完全暂停的时间。比如,假如一次GC产生了100毫秒的用户线程暂停时间,这意味着在这100毫米里,用户线程完全处于不活跃状态。平均暂停时间是指在某个时间段内,用户线程在每次GC过程产生的暂停时间的平均值,最大暂停时间是在某个时间段内,用户线程在每次GC过程中产生暂停时间的最大值。

 

吞吐量 vs 用户线程暂停时间

高吞吐量和低暂停时间是应用所希望的,因为运行JVM不是为了运行垃圾回收线程的,而是能带来价值的应用系统。另外,平均暂停时间可能比较小,但是最大暂停时间却可能比较大,对于交互式应用程序,最大暂停时间应该比较小。

 

然而,高吞吐量和低暂停时间是竞争关系。比如,为了避免GC线程潜在的导致与用户线程发生线程同步和数据不一致问题,这要求GC线程在决定哪些对象可以回收,哪些对象仍然不能回收(仍然被活下来的对象引用)时的过程中,用户线程不能修改对象的状态,基于此,用户线程在GC过程中必须停下来(更确切的说,根据所用GC算法不同,用户线程可能在一次GC的某几个阶段停下来而不是完全暂停,比如CMS垃圾收集,一次GC分6个阶段,但是只有两个阶段需要暂停用户线程)。不仅如此,线程切换也会带来额外的开销:上下文切换带来的直接开销,缓存作用带来的间接开销(causes additional costs for thread scheduling: direct costs through context switches and indirect costs because of cache effects),在加上JVM内部的安全感考量,这意味着GC不仅仅带来GC线程本身的开销,还额外的增了一些开销,这些开销对于应用来说,都是"无价值"开销。因此,为了获得最大吞吐量,JVM必须尽可能少的运行GC,只有在迫不得已的情况下(比如新生代或者老年代已经满了)才运行GC。但是,这种方式也有问题,只在不得已的情况下才运行GC,那么每次运行GC时,需要做的事情会很多,比如有更多的对象积累在堆上等待回收,每次的GC时间会很高,由此引起的平均和最大暂停时间也会很高,这就要求GC不能在迫不得已的情况才运行,这回到了刚才的问题。

 

当设计GC算法或者选用给予某种GC算法的垃圾收集器时,我们要根据应用的特点选择合适的收集器,每个垃圾收集器要么只是把吞吐量和暂停时间两个目标之一作为它的设计目标,要么在两个之间做一个折中而兼顾两个目标。

 

Sun/Oracle HotSpot JVM的垃圾回收

对于老年代的垃圾回收,HotSpot JVM有两类垃圾回收算法。第一类算法目标是最大化吞吐量(面向吞吐量的垃圾回收),第二类算法目标在于缩短等待时间。第一类垃圾回收在HotSpot JVM中称为Throughput Collector。

 

吞吐量收集器的工作方式

吞吐量垃圾回收实在老年代没有足够的空间来分配对象时进行触发(分配给老年代的对象大多是从新生代升级到老年代的对象)。

1.从 "GC roots"开始,GC在老年代堆空间上查找可达对象,并将它们标记为存活状态。

2. GC把老年代上标记为存活状态的对象移动到一端,因此,这些存活的对象会占用单块连续的内存空间。这里采用的是对象移动(Move)的方式,而不是复制(copy)到另外的堆空间,因此,可以解决碎片问题。

3.将剩下的堆空间标记位可回收状态

4.吞吐量收集器使用一个或者几个GC线程来执行线程操作。当使用多个线程来进行垃圾回收时,算法分解为多个不同步骤,每个步骤由不同的GC线程进行处理,因此这些GC线程不会相互干扰,只负责自己的那块内存空间。

5.在GC过程中,所有的用户线程都会暂停。当GC结束,JVM会恢复用户线程的执行

 

 

与吞吐量相关的JVM选项

 

 

-XX:+UseSerialGC

 

使用这个选项指示JVM启动单线程(串行)的面向吞吐量的垃圾收集器。新生代和老年代都是使用单线程进行垃圾回收。这个选项通常只用于单核CPU的情况,如果只有单核而使用多线程并发的进行垃圾回收,由于频繁的线程切换,反而降低了效率

 

-XX:+UseParallelGC

 

使用这个选项指示JVM启动多个GC线程,并行的进行新生代的垃圾回收。对于Java6,使用-XX:+UseParallelOldGC更可取。而到了Java7,使用-XX:+UseParallelGC和使用-XX:+UseParallelOldGC一样的效果

 

 

-XX:+UseParallelOldGC

 

这里的Old不是老的GC算法,而是指老年代,但是这个选项的名字及其容易产生误解,以为只是对老年代进行并行回收。实际上,-XX:+UseParallelOldGC不但对老年代进行并行回收,还会对新生代进行并行的垃圾回收。如果是多核CPU并且高吞吐量是一个希望的目标,那么应该加上这个选项。吞吐量浏览器之所以称为吞吐量浏览器

原因就在于它把高吞吐作为这个算法的卖点。

 

 

 XX:ParallelGCThreads

 

使用-XX:ParallelGCThreads=<value>选项可以用来设定进行并行GC的线程数。例如,-XX:ParallelGCThreads=6表示使用6个线程来并行的执行GC任务。

JVM设置的默认值gcThreadNum计算方法是基于CPU的内核数,

N=Runtime.availableProcessors();

if (N <= 8) {

   gcThreadNum = N;

} else {

  gcThreadNum = 3 + 5*N/8;

}

通常,可以使用JVM提供的默认值,但是如果一台服务器上有多个JVM进程,那么应该将值设置的小一些以避免多个JVM进程的GC线程过多导致的并发竞争。此时的N就是CPU内核数除以JVM进程数

 

-XX:UseAdaptiveSizePolicy

吞吐量垃圾回收提供了一个很有趣但是在现代JVM上很普遍的特性以提升GC配置的用户友好性。这个特性是"ergomics"的一部分。"ergomics"这个概念是Sun HotSpot JVM在Java5引进的概念。它使得GC回收器能够动态自适应的做出是否要应用用户所做的参数设置,比如堆区的大小以及GC的设置。如果JVM能够判定,应用用户所作的设置能够提升GC性能则应用,否则继续采用默认值。"提升GC性能"的含义是由用户通过选项-XX:GCTimeRatio and -XX:MaxGCPauseMillis进行设置的(这两个选项就是关于暂停时间和吞吐量这两个衡量GC算法的指标的设置)。

 

"ergomics"是默认开启的,JVM GC自适应的特性是现代JVM最强大的功能之一。不过,有时候,我们可能能够确切的知道对一个具体的应用什么样的设置是最好的,在这种情况下,我们不希望JVM加入自适应的判断逻辑,那么可以使用将这个选项-XX:-UseAdaptiveSizePolicy去掉

 

 

-XX:GCTimeRatio

使用 -XX:GCTimeRatio=<value>,我们是告诉JVM,我们所希望达到的吞吐量目标。更确切的说,以-XX:GCTimeRatio=N为例,N/N+1即是应用线程的CPU运行时间占(应用线程运行时间+GC线程运行时间)的比例。比如N=99,表示用户线程的运行是99/100,而GC线程则占1/100。

那么,JVM在运行时,会自动的调整堆和GC的配置以达到这个目标。-XX:GCTimeRatio的默认值是99,即99%的时间运行用户线程,1%的时间运行应用线程。

 

-XX:MaxGCPauseMillis

 

-XX:MaxGCPauseMillis=<value>这个选项是要告诉JVM用户线程所希望的最大的暂停时间(ms为单位)。JVM在运行时,吞吐量垃圾回收器会进行暂停时间统计(基于加权平均和标准方差)

如果统计结果表明,GC导致的暂停时间有可能超过用户所希望的最大暂停时间,那么JVM会动态调整堆和GC的设置来降低最大等待时间。

 

需要注意的是,

1. 新生代和老年代的垃圾回收分别统计计算

2. 默认情况下,JVM没有设置最大的暂停时间

3.如果 -XX:GCTimeRatio=<value>和-XX:MaxGCPauseMillis=<value>这两个竞争的目标都设置了,那么-XX:MaxGCPauseMillis=<value>有更高的优先级,即-XX:GCTimeRatio=<value>将被忽略

 

4. 当设置-XX:MaxGCPauseMillis=<value>时,需要注意,这个值不能设置的过小,因为为了降低最大暂停时间,JVM会增加GC的数量(频繁GC),这将严重的影响吞吐量(相当于把最大时间分解到多次GC中了)

对于暂停时间少这个目标要求很高的话,比如web交互式应用,那么吞吐量GC不是很合适,应该选用CMS垃圾收集器。

 

本文参考:https://blog.codecentric.de/en/2013/01/useful-jvm-flags-part-6-throughput-collector/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    JvmGC收集器

    在 Java 虚拟机中,GC(Garbage Collection)收集器是 JVM 的一个重要组件,它负责回收 Java 应用程序中的垃圾对象,从而维持应用程序的性能和可靠性。JvmGC 收集器是 JVM 中的三个主要 GC 收集器之一,分别是 ...

    JVM之垃圾回收器

    - **Throughput GC**:追求高吞吐量,与Parallel GC类似,但在老年代使用了标记-压缩算法。 - **Concurrent Mark Sweep (CMS) GC**:并发收集,低暂停时间,适用于响应时间敏感的应用。新生代通常搭配ParNew GC,...

    JVM垃圾收集器全面详解

    Parallel GC也称为Throughput Collector,用于新生代和老年代,通过多线程提高垃圾回收效率,追求高吞吐量,适合CPU资源丰富的服务器环境。 4. **CMS (Concurrent Mark Sweep) GC** CMS是一款并发垃圾收集器,...

    性能工程师指南:玩转OpenJDK HotSpot垃圾收集器

    - 吞吐量最大化策略:采用分代收集方式,年轻代使用并行工作线程,老年代采用并发标记/清扫过程。 - 延迟敏感策略:减少停顿时间,仅在必要时进行暂停。 4. **OpenJDK HotSpot中的GC**: - 平行GC(ParallelGC):...

    java垃圾回收器代码举例

    - **Throughput Collector**:基于Parallel Collector,旨在提高总体应用程序吞吐量。 - **CMS(Concurrent Mark Sweep)Collector**:并发标记清除收集器,尽量减少停顿时间,适合响应时间敏感的应用。 - **G1...

    Java理解Throughput收集器.pdf

    本文主要讨论的是Throughput收集器,这是一种专注于提高应用程序总体吞吐量的垃圾收集策略。 Throughput收集器的主要目标是在保持较高程序运行速度的同时,尽可能减少垃圾收集过程对应用程序性能的影响。它的工作...

    垃圾回收相关总结

    当出现"Concurrent Mode Failure"时,JVM会切换到Serial Old收集器进行老年代的回收,以确保系统的稳定。 4. **并行化目标与吞吐量** 并行化GC的主要目的是提高吞吐量,即程序运行时间与总时间的比例。Parallel ...

    Java 7 - GC cheatsheet

    它使用多个垃圾回收线程并行回收垃圾,以此提升应用程序的吞吐量。通过参数-XX:+UseParallelGC启用,并行新生代收集器;使用-XX:+UseParallelOldGC启用并行老年代收集器。 3. Concurrent Mark Sweep(CMS)回收器:...

    JVM_GC_-调优总结.pdf

    - **定义**: GC(Garbage Collection),即垃圾收集器,用于跟踪内存中的对象,并自动回收那些不再被其他对象引用的对象,释放这部分内存空间供其他对象使用。 - **对象类型**: - **活动对象**: 当前正在被其他...

    java_jvm_

    了解并熟练掌握JVM的垃圾回收机制,结合不同的垃圾收集器特性,可以有效地优化Java应用的内存使用和性能表现。在实际开发中,我们可以通过配置JVM参数来调整垃圾回收行为,以满足特定的应用需求。

    java垃圾回收机制参考.pdf

    2. **吞吐量(Throughput)**:GC会消耗CPU资源,过多的GC活动可能导致总体应用性能下降。 3. **内存碎片(Memory Fragmentation)**:如果不进行内存整理,长期的GC可能导致内存碎片,降低内存利用率。 4. **对象...

    GC4 专项储备.zip

    2. 提高吞吐量(Throughput):优化垃圾收集的效率,使系统能够更快地完成内存回收,从而提高整体应用性能。 三、GC4的实现技术 GC4可能采用了包括以下技术在内的组合: 1. 并发标记清除(Concurrent Mark Sweep,...

    并发串行GC上传GCEasy的诊断图1

    【并发串行GC上传GCEasy的诊断图1】是一个关于Java垃圾收集器性能分析的报告,通过GCEasy工具进行诊断。这个报告主要关注的是JVM内存使用情况、性能指标(KPIs)、GC智能报告、内存分配、垃圾收集时间分布以及交互...

    GCViewer.zip

    GCViewer由Stefan Zeiger开发,主要功能是解析JVM的日志文件,并以图表形式展示垃圾收集的详细信息,包括GC的执行时间、内存区域的变化、吞吐量等关键指标。这对于诊断内存泄漏、优化内存配置以及理解垃圾收集算法的...

    JVM内存设置与调优指南

    选择合适的收集器取决于应用的特性和需求,如响应时间、吞吐量或低停顿时间。 调优过程中,我们需要关注以下指标: - **GC频率**:过高可能意味着内存分配不合理或存在内存泄漏。 - **暂停时间(Pause Time)**:...

    jdk20-hotspot-virtual-machine-garbage-collection-tuni

    **垃圾收集调优参数**:通过JVM参数可以调整GC行为,例如`-Xms`和`-Xmx`设置堆大小,`-XX:NewRatio`调整年轻代与老年代的比例,`-XX:SurvivorRatio`设置Survivor区的比例,`-XX:+UseConcMarkSweepGC`启用CMS收集器等...

    团队合作:Java垃圾回收与各种GC算法

    2. **Parallel GC**:也称为Throughput Collector,它在多CPU环境下提升性能,通过并行处理垃圾回收来增加吞吐量,但同样会有"Stop-The-World"现象。 3. **CMS (Concurrent Mark Sweep)**:此收集器尝试减少垃圾...

    hotspot-virtual-machine-garbage-collection-tuning-guide.pdf

    4. **G1垃圾收集器(G1 Garbage Collector)**:G1是一种新生代和老年代都进行并发收集的垃圾收集器,目标是实现可预测的暂停时间模型。G1会将堆划分为多个区域,并尝试预测和控制每次GC的暂停时间。 在选择垃圾...

    JVM基础知识部分,帮助初识JVM

    5. **内存调优(Tuning)**:包括堆大小设置、新生代与老年代比例、GC停顿时间目标(GCTimeRatio)、吞吐量目标(Throughput)等,通过调整这些参数可以优化JVM的性能。 6. **类加载机制**:Java类的加载、连接和初始...

Global site tag (gtag.js) - Google Analytics