【Java 8 GC 调优】Ergonomics
(不知道把 Ergonomics 翻译成什么比较合适。)
Ergonomics 是 “JVM” 和 “GC调优” 提高应用程序性能的过程(如,基于行为的调优)。JVM 根据所运行的平台提供了 GC、堆大小、运行时编译器 等方面的默认选择。这些选择符合不同类型应用程序的需求,可减少命令行(参数)调整。此外,基于行为的调优会动态调整堆大小,来满足应用程序的特殊行为。
本节介绍这些默认选择和基于行为的调优。在使用后续章节中描述的更详细的控制之前,先使用这些默认值。
GC、堆、运行时编译器 的默认选择
具有以下属性的机器会被定义为服务器类的机器:
- 2个或以上物理处理器
- 2GB 或以上物理内存
在服务器类机器上默认使用以下选择:
- 吞吐量GC
- 初始堆大小为 1/64 的物理内存,最大不超过 1GB
- 最大堆大小为 1/4 的物理内存,最大不超过 1GB
- 运行时编译器为 Server
64位操作系统中 堆大小 的 初始值 和 最大值 可参考章节《The Parallel Collector》中 “Default Heap Size”。
服务器类机器的定义适用于 除了运行Windows的32位平台之外的 所有平台。下表展示了不同平台中 运行时编译器 的默认选择。
平台 | 操作系统 | 默认编译器 | Server类机器上默认编译器 |
i586 | Linux | Client | Server |
i586 | Windows | Client | Client (注1) |
SPARC(64位) | Solaris | Server | Server(注2) |
AMD(64位) | Linux | Server | Server(注2) |
AMD(64位) | Windows | Server | Server(注2) |
- 注1:即使在服务器类机器上也使用 Client 运行时编译器。因为历史上,在该组合下运行客户端程序的情况更多(如,交互应用)。
- 注2:只支持 Server 运行时编译器。
基于行为的调优
对于 并行收集器,Java SE 提供了两个 GC调优参数。它们基于应用程序的两个目标:最大暂停时间 和 吞吐量。可参考《The Parallel Collector》。(这两个选项在其它收集器中不可用。)需要注意的是这两个目标并不总是能达到。应用程序需要一个足够大的堆,至少能存放所有存活数据。此外,最小堆大小 可能会阻碍这些期望目标的达成。
最大暂停时间
暂停时间 是 GC停止应用程序 并 恢复不再使用的空间 的持续时间。“最大暂停时间目标”的目的就是为了限制这个暂停的最长持续时间。GC会维护这个暂停时间的平均值与方差。平均值是从开始运行时计算的,且会加权;最近暂停的权重更高。如果平均值加上方差 大于 最大暂停时间目标,就会被GC认为没有达到目标。
最大暂停时间目标可以通过命令行选项指定:
-XX:MaxGCPauseMillis=<nnn>
它会被解释为对 GC 的提示:期望暂停时间小于等于 毫秒。GC 会调整 堆大小 和 其它相关参数,以保持垃圾收集暂停时间小于秒。默认情况下,没有最大暂停时间目标。这些调整可能会导致频繁发生GC,从而降低应用程序的吞吐量。GC会试图优先满足任何暂停时间目标。其优先级高于吞吐量目标。尽管如此,某些情况下还是无法达成期望的暂停时间目标。
吞吐量
吞吐量是以 垃圾收集所花时间 和 其它时间(称为应用程序时间)(的比率)来衡量的。可通过命令行选项指定该目标:
-XX:GCTimeRatio=<nnn>
GC时间 与 应用程序时间 的比率为 1 / (1+) 。如,-XX:GCTimeRatio=19 表示设定的 GC时间目标为总时间的 1/20(5%)。
垃圾收集所花费的时间是收集新生代和老年代所耗时间之和。如果不满足吞吐量目标,GC会增加新生代和老年代的容量,以增加应用程序在垃圾收集操作之间的运行时长。
最小内存占用
如果吞吐量和最大暂停时间目标都达到了,那么GC会减小堆容量,直到其中一个目标不满足(总是吞吐量目标不满足)。然后解决未实现的目标。
调优策略
不要指定一个最大堆内存,除非你知道你需要一个比默认值更大的堆。
选择一个足以满足你的应用程序的吞吐量目标。
堆可能会增大或缩小,以满足指定的吞吐量目标。应用程序行为的改变可能导致堆增大或缩小。例如,当应用程序开始更快地分配内存时,为了保持相同的吞吐量,堆会增大。
如果堆增大到了最大值,但还未满足吞吐量目标,那说明这个最大值对此吞吐量目标来说太小。可以将最大堆大小设置为接*台上物理内存总量,但又不会导致应用程序内存换页的某个值。然后重新运行应用程序。如果还是不能满足吞吐量目标,那说明对这个平台来说,在使用这些可用内存的情况下,这个吞吐量目标(即,应用程序时间目标)太高了。
如果可以满足吞吐量目标,但是部分暂停时间太长,那么可以指定一个最大暂停时间目标。指定一个最大暂停时间目标可能意味着无法满足吞吐量目标。因此需要选择一个对应用程序来说可接受的折中方案的值。
当GC试图满足存在竞争关系的目标时,堆的大小通常会发生波动。即使应用程序已经达到了一个稳定的状态,也会发生波动。吞吐量、最大暂停时间、最小占用内存 这几个目标之间存在竞争关系。吞吐量目标可能需要更大的堆,最大暂停时间和最小占用内存 都可能需要较小的堆。