铁匠 铁匠
首页
收藏
java
架构之路
常用算法
  • Java
  • nginx
  • 系统运维
  • 系统安全
  • mysql
  • redis
参考文档
关于
链接
  • 分类
  • 标签
  • 归档

专注、不予评判地关注当下
首页
收藏
java
架构之路
常用算法
  • Java
  • nginx
  • 系统运维
  • 系统安全
  • mysql
  • redis
参考文档
关于
链接
  • 分类
  • 标签
  • 归档
  • java api 文档
  • 集合

  • 版本特性

  • jvm

    • JVM 结构体系
    • JVM 内存区域划分
    • JVM 垃圾收集
    • JVM 参数配置
      • 参数说明
      • 推荐配置
      • 查看进程启动参数
      • 配置说明
        • 系统参数
        • 堆内存参数
        • 堆外内存参数
        • GC配置参数
        • G1 配置参数
        • JVM 日志相关参数
    • JVM 监控分析工具
    • JVM 类加载器过程
    • 自己动手写一个 java 热加载插件
  • 网络编程

  • 并发编程

  • java
  • jvm
FengJianxin
2019-09-17
目录

JVM 参数配置

# 参数说明

  • jvm参数分为:标准参数(以-开始)与非标准参数;

    可以通过java -help查看所有标准参数

  • 非标准参数又分两种

    • 不太标准(以-X开始),特定JVM厂商的参数。java -X可以打印出当前JVM版本所有非标准参数

      $ java -X
          -Xmixed           混合模式执行 (默认)
          -Xint             仅解释模式执行
          -Xbootclasspath:<用 : 分隔的目录和 zip/jar 文件>
                          设置搜索路径以引导类和资源
          -Xbootclasspath/a:<用 : 分隔的目录和 zip/jar 文件>
                          附加在引导类路径末尾
          -Xbootclasspath/p:<用 : 分隔的目录和 zip/jar 文件>
                          置于引导类路径之前
          -Xdiag            显示附加诊断消息
          -Xnoclassgc       禁用类垃圾收集
          -Xincgc           启用增量垃圾收集
          -Xloggc:<file>    将 GC 状态记录在文件中 (带时间戳)
          -Xbatch           禁用后台编译
          -Xms<size>        设置初始 Java 堆大小
          -Xmx<size>        设置最大 Java 堆大小
          -Xss<size>        设置 Java 线程堆栈大小
          -Xprof            输出 cpu 配置文件数据
          -Xfuture          启用最严格的检查, 预期将来的默认值
          -Xrs              减少 Java/VM 对操作系统信号的使用 (请参阅文档)
          -Xcheck:jni       对 JNI 函数执行其他检查
          -Xshare:off       不尝试使用共享类数据
          -Xshare:auto      在可能的情况下使用共享类数据 (默认)
          -Xshare:on        要求使用共享类数据, 否则将失败。
          -XshowSettings    显示所有设置并继续
          -XshowSettings:all
                          显示所有设置并继续
          -XshowSettings:vm 显示所有与 vm 相关的设置并继续
          -XshowSettings:properties
                          显示所有属性设置并继续
          -XshowSettings:locale
                          显示所有与区域设置相关的设置并继续
      
      -X 选项是非标准选项, 如有更改, 恕不另行通知。
      
      
      以下选项为 Mac OS X 特定的选项:
          -XstartOnFirstThread
                          在第一个 (AppKit) 线程上运行 main() 方法
          -Xdock:name=<应用程序名称>"
                          覆盖停靠栏中显示的默认应用程序名称
          -Xdock:icon=<图标文件的路径>
                          覆盖停靠栏中显示的默认图标
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
    • 特别不标准(以-XX开始),不同版本可能会废弃

      • java -XX:+PrintFlagsInitial可以查看参数默认值(所有参数太多,可以grep过滤下)
      $ java -XX:+PrintFlagsInitial
      [Global flags]
          intx ActiveProcessorCount                      = -1                                  {product}
          uintx AdaptiveSizeDecrementScaleFactor          = 4                                   {product}
          uintx AdaptiveSizeMajorGCDecayTimeScale         = 10                                  {product}
          uintx AdaptiveSizePausePolicy                   = 0                                   {product}
          uintx AdaptiveSizePolicyCollectionCostMargin    = 50                                  {product}
          uintx AdaptiveSizePolicyInitializingSteps       = 20                                  {product}
          uintx AdaptiveSizePolicyOutputInterval          = 0                                   {product}
          uintx AdaptiveSizePolicyWeight                  = 10                                  {product}
          uintx AdaptiveSizeThroughPutPolicy              = 0                                   {product}
          uintx AdaptiveTimeWeight                        = 25                                  {product}
          bool AdjustConcurrency                         = false                               {product}
          bool AggressiveHeap                            = false                               {product}
          bool AggressiveOpts                            = false                               {product}
          intx AliasLevel                                = 3                                   {C2 product}
          bool AlignVector                               = true                                {C2 product}
          intx AllocateInstancePrefetchLines             = 1                                   {product}
          intx AllocatePrefetchDistance                  = -1                                  {product}
          intx AllocatePrefetchInstr                     = 0                                   {product}
          intx AllocatePrefetchLines                     = 3                                   {product}
          intx AllocatePrefetchStepSize                  = 16                                  {product}
          intx AllocatePrefetchStyle                     = 1                                   {product}
          bool AllowJNIEnvProxy                          = false                               {product}
          bool AllowNonVirtualCalls                      = false                               {product}
          
          ...
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      • java -XX:+PrintFlagsFinal -version(-version也可以是其他可执行class),可以用来测试我们的参数组合最终的值是什么,启动会不会报错等
      $ java -XX:+UseParallelOldGC -XX:+PrintFlagsFinal -version | grep UseParallel
          bool UseParallelGC                             = true                                {product}
          bool UseParallelOldGC                         := true                                {product}
      
      
      $ java -XX:+UseG1GC -XX:+PrintFlagsFinal -version | grep G1GC
          bool UseG1GC                                  := true                                {product}
      
      1
      2
      3
      4
      5
      6
      7
  • XX参数:

    • 布尔类型的参数,有”+”或”-“。例如,-XX:+用于激活选项,而-XX:-用于注销选项
    • 非布尔值的参数,如string或者integer,我们先写参数的名称,后面加上”=”,最后赋值。例如, -XX:=给赋值

# 推荐配置

可以通过https://opts.console.perfma.com/ (opens new window),生成推荐配置

JDK8 G1GC示例

-server -Xmx6g -Xms6g -XX:MaxMetaspaceSize=512M -XX:MetaspaceSize=512M 
-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+ParallelRefProcEnabled
-XX:ErrorFile=logs/hs_err_pid%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs -Xloggc:logs/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=10M
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintCommandLineFlags -XX:+PrintGCApplicationStoppedTime -XX:+PrintHeapAtGC
1
2
3
4

# 查看进程启动参数

通过下面命令可以查看当前启动java进程的jvm启动参数

jcmd $pid VM.flags 
jmap -heap $pid 
jinfo -flags $pid
jps -v
1
2
3
4

# 配置说明

# 系统参数

系统参数以-D指定,通过System.getProperty读取

-Djava.security.egd=file:/dev/./urandom
-Djava.net.preferIPv4Stack=true
-Djava.awt.headless=true
-Dspring.profiles.active=dev
1
2
3
4

# 堆内存参数

  • -Xms4g: 堆(Heap)的初始化大小

  • -Xmx4g: 堆(Heap)的最大值

    Xms和Xmx设置一样,可以减轻伸缩堆大小带来的压力

  • -Xmn2g: 新生代的大小,等价参数-XX:MaxNewSize=2g -XX:NewSize=2g

    G1 GC下建议不设置该参数

  • -Xss512K: 每个线程的堆栈大小,默认值1m

    一般来说256就足够了

  • -XX:PermSize=256m: 永久代初始化大小(1.8 之后使用元空间替代)

  • -XX:MaxPermSize=256m: 永久代最大内存大小(1.8 之后使用元空间替代)

    到达后会触发FullGC,有时候我们会发现老生代使用很少,但是不断在做Full GC,可能就是Perm满了导致的

  • -XX:InitialBootClassLoaderMetaspaceSize=128m: 64位下默认4M,32位下默认2200K

    这个参数决定了NoKlass Metaspace的第一个内存Block的大小,即2*InitialBootClassLoaderMetaspaceSize

  • -XX:MaxMetaspaceSize=2g: 元数据区大小,默认是无穷大(int最大值)

    最好设置这个参数,否则可能导致metaspace无限制增加

  • -XX:NewRatio: 老年代/新生代的比例,默认值是2,即:老年代是新生代的2倍

  • -XX:SurvivorRatio: Eden区和Survivor(from/to)的比例,默认值是8,即:8:1:1(Eden:from:to)

  • -XX:+UseAdaptiveSizePolicy: 是否开启动态调整堆中各区的大小,jdk1.8默认开启

    并且最好不要关闭这个选项,除非对各区划分有明确规划 | -XX:+UseAdaptiveSizePolicy(开启),-XX:-UseAdaptiveSizePolicy(关闭)

# 堆外内存参数

  • -XX:MaxDirectMemorySize=1g: 堆外内存最大值,默认为Heap区总内存减去一个Survivor区的大小

    使用ByteBuffer.allocateDirect()得到一个DirectByteBuffer对象,如果已经超限,会主动执行Sytem.gc(),期待能主动回收一点堆外内存。然后休眠一百毫秒,如果totalCapacity没有降下来,且内存还是不足,就抛出OOM

# GC配置参数

  • -XX:MaxTenuringThreshold: 新生代晋升老年代阈值(Monor GC后没有被回收的次数),CMS中默认值为6,G1中默认值为15

  • -XX:ParallelGCThreads=4: GC并发收集线程数,默认值2(linux)

    社区讨论https://club.perfma.com/topic/ParallelGCThreads (opens new window)

  • -XX:GCTimeRatio=99: 垃圾回收时间与程序运行时间的百分比,公式:1/(1+n),默认值99

  • -XX:+DisableExplicitGC: 是否禁用system.gc()

    System GC是保护机制(如堆外内存满时清理它的堆内引用对象),禁了system.gc() 未必是好事,只要没用什么特别烂的类库,真有人调了总有调的原因。

  • -XX:+PrintTenuringDistribution: 打印YGC各个年龄段的对象分布

  • -XX:ConcGCThreads=n: 并发收集线程数,默认等于cpu核心数

# G1 配置参数

  • ‐XX:+UseG1GC: 开启 G1 收集器
  • ‐XX:G1HeapRegionSize: 每个 region 区域大小,必须是默认 = 总堆空间 / 2048
  • -XX:MaxGCPauseMillis=200: GC 最大停顿时间,只对 G1 和 Parallel Scavenge 收集器有效
  • -XX:InitiatingHeapOccupancyPercent: 老年代内存占用打到设置(默认45,即45%)比例时,进行混合回收(MixedGC)
  • -XX:G1MixedGCLiveThresholdPercent=n: MixedGC 时,只有 存活对象低于这个比例才会被回收,默认 85(即 85%)
  • -XX:G1OldCSetRegionThresholdPercent=n: Mixed GC 时,能选入 CSet 的最多 old region 数量,默认 10 (即 10%)

提示

G1MixedGCLiveThresholdPercent 和 G1OldCSetRegionThresholdPercent 两个参数必须配合参数-XX:+UnlockExperimentalVMOptions 使用,并且只能加在 UnlockExperimentalVMOptions 后才能生效

# JVM 日志相关参数

  • -Xloggc | GC日志文件的输出路径

    jvm启动前路径必须存在

  • -XX:+PrintGC: 输出GC日志

  • verbose:gc: 与-XX:+PrintGC等价

  • -XX:+PrintGCDetails: 输出GC详细日志

  • -XX:+PrintGCTimeStamps: 输出GC时间戳

    格式:289.556,表示从jvm启动到发生垃圾回收所经历的的时间

  • -XX:+PrintGCDateStamps: 输出GC发生时间

    格式:2018-07-28T21:30:50.234+0800

  • -XX:+PrintGCApplicationStoppedTime: 打印完整的GC停顿时间

    例如:2019-09-20T09:30:00.204+0800: 33729.026: Total time for which application threads were stopped: 0.0059280 seconds, Stopping threads took: 0.0001000 seconds

  • -XX:+PrintHeapAtGC: 在进行GC的前后打印出堆信息

  • -XX:+PrintCommandLineFlags: 让JVM打印出那些已经被用户或者JVM设置过的详细的XX参数的名称和值,还会打印出以及因为这些参数隐式影响的参数。默认关闭

  • -XX:+PrintGCCause: 打印产生GC的原因,JDK8默认打开,JDK7要显式打开

  • -XX:ErrorFile: JVM crash时,hotspot 会生成一个error文件,提供JVM状态信息的细节

    -XX:ErrorFile=${LOGDIR}/jvmerr_%p.log,输出到指定的路径方便查找

  • -XX:+HeapDumpOnOutOfMemoryError: 在OOM,JVM快死掉的时候,输出Heap Dump到指定文件

    两个参数要配合使用 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOGDIR}/,路径只指向目录,JVM会保持文件名的唯一性,叫java_pid${pid}.hprof。因为如果指向文件,而文件已存在,反而不能写入。在容器环境下,输出4G的HeapDump,在普通硬盘上会造成20秒以上的硬盘IO跑满,影响到同一宿主机上所有其他的容器

Reference

  • 一份JVM参数 (opens new window)
  • 作为高级开发,你懂这些 JVM 参数吗 (opens new window)
#jvm
JVM 垃圾收集
JVM 监控分析工具

← JVM 垃圾收集 JVM 监控分析工具→

最近更新
01
策略模式
01-09
02
模板方法
01-06
03
观察者模式
01-06
更多文章>
Theme by Vdoing | Copyright © 2016-2023 铁匠 | 粤ICP备15021633号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式