人体工程学是 Java 虚拟机 (JVM) 和垃圾收集启发式(例如基于行为的启发式)提高应用程序性能的过程。


JVM 为垃圾收集器、堆大小和运行时编译器提供了平台相关的默认选择。这些选择满足不同类型应用程序的需求,同时需要较少的命令行调整。此外,基于行为的调优能动态优化堆的大小以满足应用程序的指定行为。本节介绍这些默认选择和基于行为的调整。在使用后续部分中描述的更详细的控制之前,请先使用这些默认值。

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


以下是有关垃圾收集器、堆大小和运行时编译器默认选择的信息。

被称为服务器级的机器被定义为具有以下特性的机器:

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


在服务器级机器上,默认选择以下选项:

  • 垃圾优先 (G1) 收集器
  • 初始堆大小为物理内存的 1/64
  • 最大堆大小为物理内存的 1/4
  • 分层编译器,同时使用 C1 和 C2

基于行为的调优

Java HotSpot VM 垃圾收集器可以配置为优先满足以下两个目标之一:最大暂停时间和应用程序吞吐量如果达到首选目标,收集器将尝试最大化另一个。自然,这些目标不可能总是得到满足:应用程序需要一个最小的堆来保存至少所有的实时数据,而其他配置可能会阻止实现部分或全部所需的目标。

最大暂停时间目标


暂停时间是垃圾收集器停止应用程序并恢复不再使用的空间的持续时间。最大暂停时间目标的目的是限制这些暂停中的最长时间。

垃圾收集器维护平均暂停时间和该平均值的方差。从执行开始时取平均值,它是加权的,所以最近的停顿会更重要。如果平均值加上暂停时间的方差大于最大暂停时间目标,则垃圾收集器认为未达到目标最大暂停时间目标由命令行选项-XX:MaxGCPauseMillis= 指定

这被解释为对垃圾收集器的提示,即需要毫秒或更短的暂停时间。垃圾收集器会调整 Java 堆大小和其他与垃圾收集相关的参数,以尝试使垃圾收集暂停短于毫秒。最大暂停时间目标的默认值因收集器而异。这些调整可能会导致垃圾收集更频繁地发生从而降低应用程序的整体吞吐量。但是,在某些情况下,无法达到所需的暂停时间目标

吞吐量目标

吞吐量目标是根据收集垃圾所花费的时间来衡量的,而在垃圾收集之外所花费的时间是应用程序时间。吞吐量目标目标由命令行选项-XX:GCTimeRatio=nnn指定。垃圾回收时间与应用程序时间之比为 1/ (1+ nnn )。例如,-XX:GCTimeRatio=19 将垃圾收集总时间的 1/20 或 5% 设定为目标。

垃圾收集所花费的时间是所有垃圾收集引起的暂停的总时间。如果未达到吞吐量目标,则垃圾收集器的一种可能操作是增加堆的大小,应用程序在收集暂停之间花费的时间可能更长

脚印

如果达到了吞吐量和最大暂停时间目标,则垃圾收集器会减小堆的大小,直到无法满足其中一个目标(始终是吞吐量目标)。垃圾收集器可以使用的最小和最大堆大小可以分别使用-Xms=-Xmx= 设置为最小和最大堆大小。

调优策略

堆增长或缩小到支持所选吞吐量目标的大小。了解堆调整策略,例如选择最大堆大小和选择最大暂停时间目标。不要为堆选择最大值,除非您知道需要一个大于默认最大堆大小的堆。选择一个足以满足您的应用程序的吞吐量目标。应用程序行为的更改可能会导致堆增长或收缩。例如,如果应用程序以更高的速率开始分配,那么堆将增长以保持相同的吞吐量。

如果堆增长到其最大大小并且未满足吞吐量目标,则最大堆大小对于吞吐量目标来说太小了。将最大堆大小设置为接近平台上总物理内存的值,但不会导致应用程序交换。再次执行应用程序。如果仍然没有达到吞吐量目标,则应用时间的目标对于平台上的可用内存来说太高了。

如果可以达到吞吐量目标,但暂停时间太长,则选择最大暂停时间目标。选择最大暂停时间目标可能意味着无法满足您的吞吐量目标,因此请选择应用程序可接受的折衷值。当垃圾收集器试图满足竞争目标时,堆的大小通常会发生波动。即使应用程序已达到稳定状态,也是如此。实现吞吐量目标(可能需要更大的堆)的压力与最大暂停时间和最小占用空间(两者都可能需要小堆)的目标相竞争。