Java 8 垃圾收集调优指南1-工效学(译)

概述

工效学(Ergonomics)就是通过 JVM 和垃圾收集器调优(例如基于行为的调优)来改进应用性能的过程。JVM 为垃圾收集器(garbage collector)、堆大小(heap size)和运行时编译器(runtime compiler)提供了依赖于平台的默认选择。这些选择可以满足不同类型应用的需求,但只需更少的命令行调优。此外,基于行为的调优(behavior-based tuning)动态地调整堆的大小来满足应用特有的行为。

请先使用这些默认值,然后再考虑使用后续章节中描述的更详细的控制。

垃圾收集器、堆和运行时编译器的默认选择

有如下配置的机器被称为服务器级别的机器:

  • 2 个或更多的物理处理器
  • 2 GB 或更多的物理内存

在服务器级别的机器上,默认的选择如下:

  • 吞吐量垃圾收集器(throughput garbage collector)
  • 初始堆大小为物理内存的 1/64,高达 1 G
  • 最大堆大小为物理内存的 1/4,高达 1 G
  • Server runtime compiler

关于 64 位系统中初始堆大小和最大堆大小,请看 The Parallel CollectorDefault Heap Size_部分。

服务器级别的机器之定义适用于所有平台,除了运行着 Windows 的 32 位平台。运行时编译器有两个选择:client、server,可通过命令行选项来覆盖默认选择:-<client|server>

基于行为的调优(Behavior-Based Tuning)

对于 parallel collector,Java SE 提供了两个可调参数来帮助应用实现其特有的行为:最大暂停时间目标和应用吞吐量目标;请看 The Parallel Collector 部分。但这两个选项在其他收集器中不可用。注意,这些行为无法总是被满足。应用需要有足够大的堆来至少容纳所有的活数据。此外,最小堆大小可能会阻止达成这些期望的目标。

最大暂停时间目标(Maximum Pause Time Goal)

暂停时间是指垃圾收集器暂停应用并回收不再使用的空间所花费的时间。这个目标的意图是限制暂停时间的最大值。暂停时间的平均值和相对于平均值的差值(variance on the average)由垃圾收集器维护。从执行一开始就计算平均值,但进行了加权处理,为了使更多最近的暂停占有更大的比例。如果平均时间加上 暂停时间相对于平均时间的差值 大于最大暂停时间目标,垃圾收集器就认为这个目标还未被实现。

最大暂停时间目标由命令行选项 -XX:MaxGCPauseMillis=<nnn> 指定。它被解释为给垃圾收集器的一个提示——期望暂停时间小于等于 <nnn> 毫秒。垃圾收集器会调整 Java 堆大小和其他与垃圾收集相关参数,来尽力保持垃圾收集暂停时间短于 <nnn> 毫秒。默认情况下没有最大暂停时间目标。这些调整可能会导致垃圾收集器更频繁地运行,进而降低了应用的总吞吐量。垃圾收集器会优先尽力满足任何暂停时间目标,然后才是吞吐量目标。然而,在某些情况下,期望的暂停时间目标还是无法被满足。

吞吐量目标(Throughput Goal)

我们使用收集垃圾花费的时间和干其他事儿所花费的时间(被称为应用时间(application time))来度量吞吐量目标。这个目标由 -XX:GCTimeRatio=<nnn> 选项指定。垃圾收集时间与应用时间(application time)的比值是 1 / (1 + <nnn>)。例如,-XX:GCTimeRatio=19 设置的目标为期望总时间的 1/20 或 5% 用于垃圾收集。

垃圾收集花费的时间是新生代和老生代加在一起的总时间。如果吞吐量目标还未被满足,就会增加各代的大小,目的是努力增加在两次收集之间应用可运行的时间。

Footprint Goal

如果吞吐量目标和最大暂停时间目标已被满足,垃圾收集器就会减小堆的大小,直到其中一个目标不能被满足(总是吞吐量目标)。然后再设法解决那个未被满足的目标。

调优策略(Tuning Strategy)

不要给堆选择一个最大值,除非你知道你需要的堆比默认的最大堆还要大。选择一个对你的应用来说足够了的吞吐量目标。

堆会增长或收缩至可支持所选择的吞吐量目标的大小。应用程序行为的改变可能导致堆增长或缩小。例如,如果应用开始以更高的速度为对象分配内存,堆就会增长以维护相同的吞吐量。

如果堆增长到它的最大大小而吞吐量目标还未被满足,那么相对于吞吐量目标来看,最大堆大小太小了。将最大堆大小设置为一个接近于此平台上全部的物理内存但又不会导致应用交换(swapping of application)的值。再次执行应用程序。如果吞吐量目标仍未满足,那么相对于此平台上可用的内存来看,应用时间(application time)的目标太高了。

如果吞吐量目标可被满足,但暂停时间又太长了,那就选择一个最大暂停时间目标。选择最大暂停时间目标可能意味着你的吞吐量目标将不会被满足,因此请选择对应用来说可接受的折衷值。

典型的情形是堆大小将随着垃圾收集器努力满足互相抗衡的目标(competing goals)而振荡(oscillate)。即使应用程序已达到稳定状态,也还是如此。实现吞吐量目标(可能需要更大的堆)的压力与最大暂停时间和最小 footprint 目标(这两个可能需要更小的堆)相互抗衡着。

参考资源

原文 Java 8 Garbage Collection Tuning Guide: Ergonomics

0%