JVM调优方法总结

JVM调优概述

本文要求读者对Java虚拟机(JVM)内部结构比较熟悉,了解虚拟机运行时有哪些数据区域,垃圾回收算法以及垃圾回收器。在此基础上本文对Java虚拟机调优的方法和思路进行了一些梳理和总结。

Java虚拟机调优:对虚拟机进行一些配置使得能够满足当前应用场景的需要。

应用场景

  • 在用途上:桌面级应用、服务器应用
  • 在要求上:响应时间优先、吞吐量优先

什么时候需要调优(比较宽泛的说法):

  • 虚拟机内部一些数据区域发生OOM(OutOfMemoryError)或SOF(StackOverflowError)
    • 在不能扩展内存大小的情况下,只能去合理的分配各个数据区域的大小
  • 因为垃圾回收过程时间太长导致用户交互体验差(用户交互场景——响应时间优先)
    • 需要合理地选择垃圾回收器,缩短垃圾回收时间,使响应更加迅速
  • 虚拟机处理任务时间长,效率低(后台运算场景——吞吐量优先)
    • 需要合理地选择垃圾回收器,提高吞吐量(即高效地利用CPU时间)

如何进行虚拟机调优

  • 一般思路为根据虚拟机抛出的异常通过日志工具分析虚拟机的日志文件,找到问题所在,根据当前应用场景,选择合适的方法去调优虚拟机。
  • 该过程是虚拟机调优最核心的部分,“分析日志准确定位问题所在”以及“结合当前应用场景选择合适方法”最是能够体现能力的地方,一方面需要不断地学习前人总结的经验,另一方面需要大量的实践积累。

Java虚拟机调优的方法

  • 选择虚拟机模式(client or server)
  • 结合当前应用场景,合理地配置运行时数据区域大小
  • 结合当前应用场景,合理地选择垃圾回收器

本文只介绍可供虚拟机调优使用的一些具体的选择和配置方法。本文可当作调优时的工具书来查阅使用;至于具体应用场景中应该选择什么合适的方法,则超出本文的范围。

虚拟机模式选择

1 Client模式和Server模式介绍

  • Client模式下采用轻量级的虚拟机,启动速度较快,运行速度较慢,对CPU和内存等资源消耗低,适用于桌面级应用场景。

  • Server模式下采用重量级的虚拟机,启动速度满,运行速度很快(对程序采用了更多的优化),对CPU和内存等资源消耗高,适用于服务器应用场景。

2 查看本地JDK支持的虚拟机模式

JVM调优方法总结

3 选择Client模式

配置文件路径
JVM调优方法总结

设置Client模式
JVM调优方法总结

命令提示符窗口验证
JVM调优方法总结

4 选择Server模式

设置Server模式
JVM调优方法总结

命令提示符窗口验证
JVM调优方法总结


运行时数据区域大小设置参数

说明:以下参数值仅为举例说明使用,实际取值应根据应用场景合理选择。
Java堆

  • -Xms20m ——Java堆最小20M(单位不区分大小写)
  • -Xmx20m ——Java堆最大20M
  • -Xmn10m ——Java堆中新生代(包括Eden区和两个Survivor区)为10M
  • -XX:SurvivorRatio=8 ——设置Eden:Survivor=8:1,默认值也为8
  • -XX:PretenureSizeThreshold=3145728 ——设置直接晋升到老年代分配内存的对象大小为3M,注意3145728不能直接写为3m(默认值是0,意味着不管对象多大都只在新生代Eden区分配)
  • -XX:MaxTenuringThreshold=15 ——设置对象经历15次Minor GC后就进入老年代
  • -XX:+HandlePromotionFailure ——设置允许担保失败,- 为不允许(该命令在 JDK 6U24中被移除)

Java虚拟机栈

  • -Xss128k ——Java虚拟机栈大小为128K

本地方法栈

  • -Xoss128k ——本地方法栈大小为128K(HotSpot虚拟机中本地方法栈和Java虚拟机栈相同,配置该参数实际会无效)

方法区(非堆)

  • -XX:PermSize=10m ——方法区最小10M
  • -XX:MaxPermSize=10m ——方法区最大10M

直接内存

  • -XX:MaxDirectMemorySize=20m ——直接内存大小为20M,若不设置默认与-Xmx一样

垃圾收集器选择和配置参数

说明:以下参数值仅为举例说明使用,实际取值应根据应用场景合理选择。
选择收集器

  • -XX:+UserSerialGC ——设置使用 Serial + Serial Old 收集器组合(Client模式下的默认收集器)
  • -XX:+UseParNewGC ——设置使用 ParNew + Serial Old 收集器组合
  • -XX:+UseParallelGC ——设置使用 Parallel Scavenge + Serial Old(PS MarkSweep) 收集器组合
  • -XX:+UseParallelOldGC ——设置使用 Parallel Scavenge + Parallel Old 收集器组合
  • -XX:+UseConcMarkSweepGC ——设置使用 ParNew + CMS + Serial Old 收集器组合(其中Serial Old是CMS发生Concurrent Mode Failure后的备用收集器)

Parallel Scavenge收集器自适应模式配置

  • -XX:+UseAdaptiveSizePolicy ——开启自适应策略,动态调整Java堆中各个区域大小以及进入老年代的年龄
  • -XX:GCTimeRatio=19 ——设置吞吐量 = 1-1/(1+19)=95%,默认值为99(即吞吐量 = 1-1/(1+99)=99%)
  • -XX:MaxGCPauseMillis=100 ——设置垃圾收集时的最大停顿时间为100ms

CMS收集器参数配置

  • -XX:CMSInitiatingOccupancyFraction=60 ——设置在老年代空间被使用60%后触发垃圾收集(默认值为68%)
  • -XX:+UseCMSCompactAtFullCollection ——设置每发生一次Full GC便进行一次老年代碎片整理
  • -XX:CMSFullGCsBeforeCompaction=5 ——设置发生5次Full GC便进行一次老年代碎片整理

设置并行和并发收集器线程数

  • -XX:ParallelGCThreads=4 ——设置垃圾回收线程数为4

获取日志信息

  • -verbose:gc ——在控制台输出GC情况
  • -XX:+PrintGCDetails ——设置虚拟机在发生垃圾回收行为时打印内存回收日志,在进程退出时输出当前内存区域的分配情况
  • -Xloggc: filepath ——将GC日志输出到指定文件中(实际应用中内存回收日志一般是打印到文件后通过日志工具进行分析)

虚拟机参数格式总结

为了能灵活地正确地使用上述参数,以下总结了虚拟机参数的格式。

HotSpot参数分类

  • - 开头:标准参数,所有的HotSpot虚拟机都支持,如 -version
  • -X 开头:非标准参数,特定版本HotSpot虚拟机支持,如 -Xms20m
  • -XX 开头:不稳定参数,下个版本可能取消,如 -XX:+PrintGCDetails

开关类参数

  • + 代表打开开关,如-XX:+UseConcMarkSweepGC(设置使用 ParNew + CMS + Serial Old 收集器组合)
  • - 代表关闭开关,如-XX:-UseConcMarkSweepGC(取消使用 ParNew + CMS + Serial Old 收集器组合)

赋值类参数

  • -X 开头赋值类参数,如-Xms20m(设置Java堆最小20M)
  • -XX 开头赋值类参数,如-XX:MaxTenuringThreshold=15(设置年轻代中对象进入老年代年龄为15)

命令类参数

  • 该类参数格式固定,如-version

参考

[1] 《深入理解Java虚拟机》
[2] JVM的Client模式与Server模式
[3] 虚拟机调优
[4] JVM 触发Full gc条件
[5] JVM 调优实战–常用命令参数及PS收集器的GC日志格式

相关文章: