https://cloud.tencent.com/developer/article/2235751

JVM参数分类

jvm 参数可分为三类:

  • 标准参数:以 “-“ 开头的参数
  • 非标准参数:以 “-X“ 开头的参数
  • 不稳定参数:以”-XX“ 开头的参数

标准参数

标准参数是指在各个JVM版本中基本保持不变,相对比较稳定。

标准参数统一都是以 “-“ 开头,如:

1

java -classpath E:/code -Dprofile=dev HelloWorld tom jack

注意:其中HelloWorld 是被运行的 HelloWorld.class。HelloWorld 之前就是设置的JVM标准参数(-classpath、-D),HelloWorld 之后的参数(tom、jack)是用来传给 main(String[] args) 方法的args数组变量的,两者位置不要放错。

查看所有标准参数

打开一个命令终端,执行 java -help,就可以展示所有的JVM标准参数。

非标准参数

非标准参数表示不保证所有JVM实现都支持这些参数,在将来的JVM版本中可能会发生改变。非标准参数统一以 -X 开头,如 -Xmx20M 设置最大java堆大小,示例:

1

java -classpath E:/code -Dfile.encoding=UTF-8 -Dprofile=dev -Xmx20M HelloWorld tom jack

查看所有非标准参数

打开一个命令终端,执行 java -X,就可以展示所有的JVM非标准参数。

不稳定参数

不稳定参数这是我们日常开发中接触到最多的参数类型,也是非标准化参数,相对来说不稳定,随着JVM版本的变化可能会发生变化,主要用于JVM调优和debug。

不稳定参数统一以 “-XX“ 开头,书写格式分为两种:

  • bool 类型:

    • -XX:+<option>:代表启用 true
    • -XX:-<option>:代表禁用 false
  • 数值或字符串类型:
    • -XX:<option>=<number>:数字如果有单位一般是 兆字节的“ m”或“ M”,千字节的“ k”或“ K”以及千兆字节的“ g”或“ G”(例如32k与32768相同)
    • -XX:<option>=<string>:字符串通常用于指定文件,路径或命令列表

如打印GC日志 -XX:+PrintGCDetails、设置对象最大晋升老年代的年龄 -XX:MaxTenuringThreshold=15,示例:

1

java -classpath E:/code -Dfile.encoding=UTF-8 -Dprofile=dev -Xmx20M -XX:+PrintGCDetails -XX:MaxTenuringThreshold=15 HelloWorld tom jack

查看所有不稳定参数

执行命令终端,执行 -XX:+PrintFlagsFinal,展示所有不稳定参数。

  • 第一列:参数类型
  • 第二列:参数名称
  • 第三列:”=“ 表示第四列是初始值,”:=“表示参数被用户或者JVM赋值了
  • 第四列:参数值
  • 第五列:参数类别

查看所有参数初始值

执行参数-XX:+PrintFlagsInitial。相对于-XX:+PrintFlagsFinal 参数,该参数打印出的结果中第四列都是初始值。

打印已经被用户或者当前虚拟机设置过的参数

执行参数-XX:+PrintCommandLineFlags。相当于列举出 -XX:+PrintFlagsFinal的结果中所有第三列是”:=“的参数。一般运行程序时,最好都加上该参数,可以知道该程序运行都设置过哪些JVM参数。

JVM参数配置说明

调优栈内存

堆大小典型配置参数

  • -Xmx:设置最大堆大小。 -Xmx3550m,设置JVM最大可用内存为3550 MB。
  • -Xms:设置JVM初始内存。 -Xms3550m,设置JVM初始内存为3550 MB。此值建议与-Xmx相同,避免每次垃圾回收完成后JVM重新分配内存。
  • -Xmn2g:设置年轻代大小。 -Xmn2g,设置年轻代大小为2 GB。整个JVM内存大小=年轻代大小+年老代大小+持久代大小。持久代一般固定大小为64 MB,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
  • -Xss:设置线程的栈大小。 -Xss128k,设置每个线程的栈大小为128 KB。 说明:JDK 5.0版本以后每个线程栈大小为1 MB,JDK 5.0以前版本每个线程栈大小为256 KB。请依据应用的线程所需内存大小进行调整。在相同物理内存下,减小该值可以生成更多的线程。但是操作系统对一个进程内的线程个数有一定的限制,无法无限生成,一般在3000个~5000个。
  • -XX:NewRatio=n:设置年轻代和年老代的比值。 -XX:NewRatio=4,设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。如果设置为4,那么年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5。
  • -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。 -XX:SurvivorRatio=4,设置年轻代中Eden区与Survivor区的大小比值。如果设置为4,那么两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6。
  • -XX:MaxPermSize=n:设置持久代大小。 -XX:MaxPermSize=16m,设置持久代大小为16 MB。
  • -XX:MaxTenuringThreshold=n:设置垃圾最大年龄。 -XX:MaxTenuringThreshold=0,设置垃圾最大年龄。如果设置为0,那么年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,提高了效率。如果将此值设置为较大值,那么年轻代对象会在Survivor区进行多次复制,增加了对象在年轻代的存活时间,增加在年轻代即被回收的概率。

调优回收器GC

吞吐量优先的GC典型配置参数

  • -XX:+UseParallelGC:选择垃圾收集器为并行收集器。 -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20-XX:+UseParallelGC此配置仅对年轻代有效,即在示例配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。
  • -XX:ParallelGCThreads:配置并行收集器的线程数,即同时多少个线程一起进行垃圾回收。此值建议配置与处理器数目相等-Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20-XX:ParallelGCThreads=20表示配置并行收集器的线程数为20个。
  • -XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集。 -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC-XX:+UseParallelOldGC表示对年老代进行并行收集。 说明:JDK 6.0支持对年老代并行收集。
  • -XX:MaxGCPauseMillis:设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。 -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100-XX:MaxGCPauseMillis=100设置每次年轻代垃圾回收的最长时间为100 ms。
  • -XX:+UseAdaptiveSizePolicy:设置此选项后,并行收集器自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低响应时该间或者收集频率,该值建议使用并行收集器时,并且一直打开。 -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy

响应时间优先的GC典型配置参数

  • -XX:+UseConcMarkSweepGC:设置年老代为并发收集。配置了-XX:+UseConcMarkSweepGC,建议年轻代大小使用-Xmn设置。 -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
  • -XX:+UseParNewGC:设置年轻代为并行收集。可与CMS收集同时使用。 说明:JDK 5.0以上版本,JVM根据系统配置自行设置,无需再设置此值。 -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
  • -XX:CMSFullGCsBeforeCompaction:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。 -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection-XX:CMSFullGCsBeforeCompaction=5,表示运行GC5次后对内存空间进行压缩、整理。
  • -XX:+UseCMSCompactAtFullCollection:打开对年老代的压缩。该值可能会影响性能,但是可以消除碎片。 -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection

用于辅助的GC典型配置参数

  • -XX:+PrintGC:用于输出GC日志。
  • -XX:+PrintGCDetails:用于输出GC日志。
  • -XX:+PrintGCTimeStamps:用于输出GC时间戳(JVM启动到当前日期的总时长的时间戳形式)。示例如下:0.855: [GC (Allocation Failure) [PSYoungGen: 33280K->5118K(38400K)] 33280K->5663K(125952K), 0.0067629 secs] [Times: user=0.01 sys=0.01, real=0.00 secs]
  • -XX:+PrintGCDateStamps:用于输出GC时间戳(日期形式)。示例如下:2022-01-27T16:22:20.885+0800: 0.299: [GC pause (G1 Evacuation Pause) (young), 0.0036685 secs]
  • -XX:+PrintHeapAtGC:在进行GC前后打印出堆的信息。
  • -Xloggc:../logs/gc.log:日志文件的输出路径。

JVM内存配置最佳实践

当设置的JVM堆空间过小时,程序会出现系统内存不足OOM(Out of Memory)的问题。特别是在容器环境下,不合理的JVM堆参数设置会导致各种异常现象产生,例如应用堆大小还未到达设置阈值或规格限制,就因为OOM导致重启等。

通过MaxRAMPercentage限制堆大小(推荐)

在容器环境下,Java只能获取服务器的配置,无法感知容器内存限制。可以通过设置-Xmx来限制JVM堆大小,但该方式存在以下问题:

  • 当规格大小调整后,需要重新设置堆大小参数。
  • 当参数设置不合理时,会出现应用堆大小未达到阈值但容器OOM被强制关闭的情况。

应用程序出现OOM问题时,会触发Linux内核的OOM Killer机制。该机制能够监控占用过大内存,尤其是瞬间消耗大量内存的进程,然后它会强制关闭某项进程以腾出内存留给系统,避免系统立刻崩溃。

推荐的JVM参数设置:

1

-XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/admin/nas/gc-${POD_IP}-$(date '+%s').log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/nas/dump-${POD_IP}-$(date '+%s').hprof

参数说明如下:

参数

说明

-XX:+UseContainerSupport

使用容器内存。允许JVM从主机读取cgroup限制,例如可用的CPU和RAM,并进行相应的配置。当容器超过内存限制时,会抛出OOM异常,而不是强制关闭容器。

-XX:MaxRAMPercentage

设置JVM使用容器内存百分比。由于存在系统组件开销,建议最大不超过75.0,推荐设置为70.0。

-XX:+PrintGCDetails

输出GC详细信息。

-XX:+PrintGCDateStamps

输出GC时间戳。日期形式,例如2019-12-24T21:53:59.234+0800。

-Xloggc:/home/admin/nas/gc-${POD_IP}-$(date '+%s').log

GC日志文件路径。需保证Log文件所在容器路径已存在,建议您将该容器路径挂载到NAS目录,以便自动创建目录以及实现日志的持久化存储。

-XX:+HeapDumpOnOutOfMemoryError

JVM发生OOM时,自动生成DUMP文件。

-XX:HeapDumpPath=/home/admin/nas/dump-${POD_IP}-$(date '+%s').hprof

DUMP文件路径。需保证DUMP文件所在容器路径已存在,建议您将该容器路径挂载到NAS目录,以便自动创建目录以及实现日志的持久化存储。

  • 该特性支持JDK 8u191+、JDK 10及以上版本。
  • 如果您没有将文件挂载到NAS目录,必须保证/home/admin/nas路径存在,否则不会产生日志。

通过Xms Xmx限制堆大小

可以通过设置-Xms-Xmx来限制堆大小,推荐的JVM参数设置:

1

-Xms2048m -Xmx2048m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/home/admin/nas/gc-${POD_IP}-$(date '+%s').log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/nas/dump-${POD_IP}-$(date '+%s').hprof

参数说明如下:

参数

说明

-Xms

设置JVM初始内存大小。建议与-Xmx相同,避免每次垃圾回收完成后JVM重新分配内存。

-Xmx

设置JVM最大可用内存大小。为避免容器OOM,请为系统预留足够的内存大小。

推荐的堆大小设置:

内存规格大小

JVM堆大小

1 GB

600 MB

2 GB

1434 MB

4 GB

2867 MB

8 GB

5734 MB

常见问题

  1. 容器出现137退出码的含义是什么? 当容器使用内存超过限制时,会出现容器OOM,导致容器被强制关闭。此时业务应用内存可能并未达到JVM堆大小上限,所以不会产生Dump日志。建议您调小JVM堆大小的上限,为容器内其他系统组件预留足够多的内存空间。
  1. 堆大小和规格内存的参数值可以相同吗? 不可以。因为系统自身组件存在内存开销,例如使用SLS进行日志收集时会占用一小部分的内存空间,所以不能将JVM堆大小设置为和规格内存大小相同的数值,需要为这些系统组件预留足够的内存空间。
  2. 在JDK 8版本下设置-XX:MaxRAMPercentage值为整数时报错怎么处理? 这是JDK 8的一个Bug。具体信息,请参见Java Bug Database。例如,在JDK 8u191版本下,设置-XX:MaxRAMPercentage=70,这时JVM会启动报错。

解决方案如下:

  • 方式一:设置-XX:MaxRAMPercentage70.0-XX:InitialRAMPercentage-XX:MinRAMPercentage参数值同样不可设置为整数,需按照浮点数形式来设置。
  • 方式二:升级JDK版本至JDK 10及以上版本。

[转帖]JVM参数配置及调优的更多相关文章

  1. JVM基本配置与调优

    JVM基本配置与调优 JVM调优,一般都是针对堆内存配置调优. 如图:堆内存分新生代和老年代,新生代又划分为eden区.from区.to区. 一.区域释义 JVM内存模型,堆内存代划分为新生代和老年代 ...

  2. JVM典型配置和调优举例

    1. 堆设置-Xms: :初始堆大小.-Xmx: :最大堆大小.-XX:NewSize=n: :设置年轻代大小.-XX:NewRatio=n: : :设置年轻代和年老代的比值.如:为 3,表示年轻代与 ...

  3. JVM性能优化--JVM参数配置,使用JMeter简单测试配合说明参数调优

    一.JVM参数配置 1.常见参数配置 -XX:+PrintGC 每次触发GC的时候打印相关日志 -XX:+UseSerialGC 串行回收 -XX:+PrintGCDetails 更详细的GC日志 - ...

  4. JVM原理讲解和调优

    一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...

  5. JVM参数配置 java内存区域

    java内存区域 一些基本概念 http://www.importnew.com/18694.html https://www.cnblogs.com/wangyayun/p/6557851.html ...

  6. 一个性能较好的JVM参数配置

    一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...

  7. 一个性能较好的JVM参数配置(转)

    一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...

  8. JVM参数配置&&命令工具

    JVM参数配置 大致方向:JVM调优的目的是保证在一定吞吐量的情况下尽可能的减少GC次数,从而减少系统停顿时间,提高服务质量和效率. 其中减少GC次数的原则: 将新生代转换成老年代的数量降至最少(及时 ...

  9. JVM底层原理及调优之笔记一

    JVM底层原理及调优 1.java虚拟机内存模型(JVM内存模型) 1.堆(-Xms -Xmx -Xmn) java堆,也称为GC堆,是JVM中所管理的内存中最大的一块内存区域,是线程共享的,在JVM ...

  10. 【CNMP系列】PHP配置和调优

    上一节我们说到PHP5.6.30在CentOS7.0下的整个安装过程,http://www.cnblogs.com/riverdubu/p/6428226.html 今天我来和大家讲解一下PHP-FP ...

随机推荐

  1. JavaFx css样式(三)

    JavaFx css样式(三) JavaFX 从入门入门到入土系列 JavaFx css样式,前面我说过它类似html,他有css控制样式,不过最新的css标准并不支持,同时javafx的css样式都 ...

  2. vue常用函数

     this.$router.back();  //回退上一页面

  3. 华为云MVP高浩:打破AI开发瓶颈,解决数据、算法、算力三大难题

    摘要:在高浩看来,大量的数字蓝领人才和AI应用开发人员构成了当前AI行业发展人才之基,这也为高校学生就业初期从事的工作指明了方向,而华为ModelArts平台在教育领域有着天然的数据.算法优势,非常适 ...

  4. 超详细教程:SpringBoot整合MybatisPlus

    摘要:本文为大家带来SpringBoot整合MybatisPlus的教程,实现SpringBoot项目中依赖数据模块进行数据操作,并进行简单测试. 本文分享自华为云社区<SpringBoot整合 ...

  5. Solon 拉取 maven 包很慢或拉不了,怎么办?

    注意:如果在 IDEA 设置里指定了 settings.xml,下面两个方案可能会失效.(或者直接拿"腾讯" 的镜像仓库地址,按自己的习惯配置) 1.可以在项目的 pom.xml ...

  6. 你好 Java!Solon v1.10.3 发布

    相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) qps 高 2- 3 倍. (更高) 运行时内存节省 1/3 ~ 1/2. (更少) 打包 ...

  7. 只需 3 步,人人都能搭建自己的 chatgpt 微信机器人

    大家好,我是徐公,大厂 6 年经验,CSDN 博客专家.最近,ChatGpt 很火,身边的人都在讨论,会不会成为下一个风口,像前几年互联网一样,迎来井喷式的发展. 徐公我最近也是在密切关注,最近,在 ...

  8. XShell、XFtp免费许可证增强:删除标签限制!

    大家好,我是DD! XShell相信大家都不陌生了,作为Windows平台下最强大的SSH工具,是大部分开发者的必备工具.但由于免费许可证的标签限制,有不少开发者会去找破解版使用.虽然功能是可以使用了 ...

  9. POJ 1236 Network of Schools (连通图 - Garbow 算法)

    POJ 1236 Network of Schools ​ 校园网:给定N所学校和网络,目标是分发软件其他学校都可收到,求①所需最少分发学校数:②若任选学校都能收到,最低新增边数. 思路:同一个强连通 ...

  10. 【每日一题】16.Treepath (LCA + DP)

    补题链接:Here 题意总结:寻找有多少条两个点之间偶数路径 看完题,很容易想到在树型中,同一层的节点必然是偶数路径到达,还有就是每隔两层的节点一样可以到达,所以我就理所应当的写了如下代码 using ...