HotSpot虚拟机垃圾收集优化教程-并行垃圾收集器

并行垃圾收集器

并行垃圾收集器(也称为吞吐量收集器)是与串行垃圾收集器类似的分代收集器。串行和并行垃圾收集器之间的主要区别在于并行垃圾收集器使用多线程去加快垃圾收集速度。

使用命令行选项-XX:+UseParallelGC启用并行垃圾收集器。默认情况下,使用该选项,minor和major垃圾收集都并行运行,以进一步减少垃圾收集开销。

  • 并行垃圾收集器线程数
  • 并行垃圾收集器分代安排
  • 并行垃圾收集器人机工程学
    • 并行垃圾收集器指定选项行为
    • 并行垃圾收集器目标的优先级
    • 并行垃圾收集器生成堆大小调整
    • 并行垃圾收集器默认堆大小
      • 并行垃圾收集器初始化和最大化堆大小规范
  • 并行垃圾收集器时间过长和OOM错误
  • 并行垃圾收集器衡量

并行垃圾收集器线程数

在具有<N>个硬件线程并且<N>大于8的机器上,并行垃圾收集器使用<N>固定的分数作为垃圾收集器的线程。

对于较大的<N>值,这个分数约为5/8。当<N>值比8小的时候,使用的分数即为<N>。在选定的平台上,分数下降到5/16。可以使用命令行选项(稍后描述)调整垃圾收集器线程的特定数量。在具有一个处理器的主机上,由于并行执行(例如同步)所需的开销,并行垃圾收集器的性能可能不如串行垃圾收集器。然而,当运行具有中型到大型堆的应用程序时,在具有两个处理器的计算机上,他的性能通常比串行垃圾收集器稍微好一些。并且当有两个以上的处理器可用时,他的性能通常比串行垃圾收集器好得多。

垃圾收集器线程的数量可以通过命令行选项-XX:ParallelGCThreads=<N>来控制。如果使用命令行选项优化堆,则并行垃圾收集器的良好性能所需的堆大小与串行收集器所需的大小相同。但是,启用并行垃圾收集器应该会缩短垃圾暂停时间。由于多个线程参与minor垃圾收集,因此在垃圾收集期间,由年轻代向年老代升级,可能会出现一些碎片。在minor垃圾收集中的每个垃圾收集线程都保留了旧一代的一部分用于提升,将可用空间划分到这些“提升缓存区”中可能会导致碎片效应。减少垃圾收集线程的数量并增大年老代的大小将减少此碎片效应(为什么会减少碎片???多线程垃圾收集并行的堆选择问题???)。

并行垃圾收集器分代安排

在并行垃圾收集器中各分代的安排是不同的。

并行垃圾收集器人机工程学

当使用-XX:+UseParallelGC选择并行垃圾收集器时,他启用一种自动优化的方式,允许指定行为,而不是指定分代堆的大小和其他低级别的调优细节。

并行垃圾收集器行为性能指定选项

可以指定最大垃圾收集器暂停时间、吞吐量和占用空间(堆大小)

  • 最大垃圾收集暂停时间:最大垃圾收集暂停时间目标用命令行选项-XX:MaxGCPauseMillis=<N>指定。这被解释为一个提示,期望暂停时间是<N>毫秒或者更小的时间。默认情况下,没有最大暂停时间目标。如果指定了暂停时间目标,则会调整堆大小和与垃圾收集相关的其他参数,以使垃圾收集暂停时间小于指定值。但是,可能并不总是满足所需的暂停时间目标。这些调整可能会导致垃圾收集器降低应用程序的总吞吐量。
  • 吞吐量:吞吐量目标是根据进行垃圾收集所花费的时间与在垃圾收集外所花费的时间(称为应用程序时间)来衡量的。目标由命令行选项-XX:GCTimeRatio=<N>指定,该选项将垃圾收集时间与应用程序时间的比率设置为1/(1 + N)。
  • 空间量(堆大小)

使用选项-Xmx<N>来指定最大堆大小。另外,垃圾收集器有一个隐藏的目标,即只要满足其他目标,就可以最小化堆的大小。(能力守恒)

并行垃圾收集器目标的优先级

目标按如下顺序处理:最大暂停时间,吞吐量和最小堆大小目标。

首先满足最大暂停时间目标,只有在达到这个目标之后,吞吐量目标才得以实现。相似地,只有在前两个目标实现之后,才会考虑足迹目标。

并行垃圾收集器分代堆大小调整

垃圾收集器保留的统计信息(如平均暂停时间)将在每次垃圾收集结束时更新。

然后进行测试以确定是否达到了目标,并且对分代堆大小进行任何必要的调整。例外的情况是显式垃圾收集,例如,调用System.gc()会忽略保留统计信息和调整分代堆大小。

通过分代堆大小的固定百分比来增量增长或者缩小分代堆大小的,以便分代可以增加或者减少到他期待的堆大小。增长和缩小分代堆大小是根据不同的速率进行的。默认情况下,增长以20%的增量增长,收缩以5%的增量收缩。使用年轻代命令行-XX:YoungGenerationSizeIncrement=<Y>和年老代命令行-XX:TenuredGenerationSizeIncrement。分代收缩的百分比由命令行标识-XX:AdaptiveSizeDecrementScaleFactor=<D>。如果增长率是X%,则收缩率为X/D%。

如果垃圾收集器决定在启动时增长分代大小,则会有一个补充的百分比被增加到增量。这种补充品随着垃圾收集次数而衰减并且没有长期的影响。这个补充品的目的是为了提升启动时的性能表现。缩小的百分比没有补充。

如果最大暂停时间目标没有被实现,那么只有一个分代的大小会收缩在一次。如果两代的暂停时间都高于目标值,则暂停时间越长的一代会首先缩小。

如果吞吐量的目标没有实现,那么两个堆分代的大小都会增长。每个分代按照其对垃圾收集总时间的贡献比例进行增加。例如,如果年轻代的垃圾收集时间占总时间的25%并且如果年轻代的完全增量为20%,则年轻代的垃圾收集时间将会增加5%???

并行垃圾收集器默认堆大小

可以使用选项-Xms(初始堆大小)和-Xmx(最大堆大小)来指定初始堆和最大堆大小。

如果知道应用程序需要多少堆才能正常工作,那么将-Xms和-Xmx设置为相同的值。如果不知道,那么JVM将首先使用初始化堆大小,然后逐步增加Java堆大小直到在堆使用和性能之间找到平衡。

其他的参数和选项会影响这些默认值。要验证默认值,请使用-XX:+PrintFlagsFinal选项并且在输出中查找-XX:MaxHeapSize。例如,在Linux上可以运行一下命令:

java -XX:+PrintFlagsFinal <GC options> -version | grep MaxHeapSize

并行垃圾收集器过长垃圾收集时间和OOM错误

如果在垃圾收集中花费了太多时间,并行收集器将抛出OOM

如果超过98%的总时间花在垃圾收集上,而恢复的堆不到2%,则抛出OOM。这个设计用于防止应用程序长时间运行,由于堆大小而没有任何进展。如果有必要可以使用命令行-XX:-UseGCOverheadLimit禁用此功能。

并行垃圾收集器衡量

并行垃圾收集器的详细垃圾收集器输出与串行垃圾收集器的输出基本相同。

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: HotSpot虚拟机垃圾收集优化教程-并行垃圾收集器

FavoriteLoading添加本文到我的收藏
  • Trackback 关闭
  • 评论 (0)
  1. 暂无评论

您必须 登陆 后才能发表评论

return top