8.1 认识垃圾收集日志

8.1.1 开启垃圾收集日志记录

以下这些标志是任何JVM应用程序都应该启用的。可以将其看作必须打开的垃圾收集日志标志。

  1. -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintTenuringDistribution
  2. -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps
标志 影响
-Xloggc:gc.log 控制垃圾收集事件写入哪个文件
-XX:+PrintGCDetails 将垃圾收集事件的详细信息写入日志
-XX:+PrintTenuringDistribution 添加对工具至关重要的垃圾收集事件额外细节
-XX:+PrintGCTimeStamps 打印垃圾收集事件的发生时间(自虚拟机启动后的秒数)
-XX:+PrintGCDateStamps 打印垃圾收集事件发生的挂钟时间

控制垃圾收集的日志滚动的标志

-XX:+UseGCLogFileRotation 打开日志文件滚动
-XX:+NumberOfGCLogFiles= 设置滚动日志文件的个数
-XX:+GCLogFileSize= 设置滚动日志文件的最大值,当文件大小超过该参数值时,日志将写入下一个文件

8.2 日志解析工具

8.3 基本垃圾收集调优

设置GC堆大小的标志

-Xms<size> 设置为堆保留的内存的最小值
-Xmx<size> 设置为堆保留的内存的最大值
-XX:MaxPermSize=<size> 设置 PermGen 允许的最大值(Java 7)
-XX:MaxMetaspaceSize=<size> 设置 Metaspace 允许的最大值(Java 8)

8.3.1 理解分配你行为

8.4 调优Parallel GC

Parallel GC(并行垃圾收集器)是最简单的收集器,因此它也是最容易调优的就并不奇怪了,不过它通常只需要最小的调优。Parallel GC的目标和取舍很清晰。

  • 完全STW
  • 垃圾收集吞吐量高/计算成本低
  • 不可能出现部分收集
  • 暂停时间会随着堆大小的增加线性增长

如果应用程序能够忍受Parallel GC的特性,那么它可能是非常有效的选择——特别是在小堆上,比如那些小于4GB的堆。
较老的设置垃圾收集堆大小的标志

-XX:NewRatio=<n> (旧标志)设置老年代与新生代的相对比例
-XX:SurvivorRatio=<n> (旧标志)设置 Survivor 空间占新生代的比例
-XX:NewSize=<n> (旧标志)设置新生代的最小值
-XX:MaxNewSize=<n> (旧标志)设置新生代的最大值
-XX:MinHeapFreeRatio (旧标志)设置堆空间最小空闲比例;当堆空间的空闲内存小于这个数值
时,扩展堆空间
-XX:MaxHeapFreeRatio (旧标志)设置堆空间最大空闲比例;当堆空间的空闲内存大于这个数值时,压缩堆空间

Survivor空间比例、新生代空间比例和堆的整体大小之间通过下面的公司连接起来

Flags set:

-XX:NewRatio=N
-XX:SurvivorRatio=K

YoungGen = 1 / (N+1) of heap
OldGen = N / (N+1) of heap

Eden = (K – 2) / K of YoungGen
Survivor1 = 1 / K of YoungGen
Survivor2 = 1 / K of YoungGen

8.5 调优CMS

8.6 调优G1

调优G1的总体目标是让终端用户只需设置堆的最大值和MaxGCPauseMillils,其他所有事情都由收集器来处理。然而,目前的实际情况离这个目标还有一定的距离。
就像CMS一样,G1自带的大量配置选项,其中一些还处于实验阶段,效果还不能完全看出来。这使得我们很难理解任何调优变化带来的影响。如果调优需要这些选项,则必须指定以下这个开关

-XX:+UnlockExperimentalVMOptions

特别是,如果要使用选项 -XX:G1NewSizePercent= 或 -XX:G1MaxNewSizePercent=,则必须指定这个选项。在未来的某个时间,其中的一些选项可能会成为主流,不再需要实验性选项标志。

G1确实会超越CMS,因为CMS并不执行压缩,所以随着时间的推移,堆会碎片化。这最终会导致并发模式失败,并且JVM需要执行一次完整的并行收集(可能会出现一次 较长的STW暂停)

在G1的情况下,只要收集器能跟上分配率,那么增加压缩就可能完全避免并发模式失败。因此对于分配率高且稳定,而且大部分对象寿命很短的应用程序,我们应该:

  • 将新生代设置得较大
  • 增加晋升阀值,可能达到最大值(15)
  • 设置该应用程序可以忍受的最长暂停时间

以这种方式配置Eden和Survivor空间,可以尽可能使正在的短寿命对象不被晋升。这既减轻了老年代的压力你,又减少了清理区域的需要。