[转帖]JVM参数配置及调优
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 |
常见问题
- 容器出现137退出码的含义是什么? 当容器使用内存超过限制时,会出现容器OOM,导致容器被强制关闭。此时业务应用内存可能并未达到JVM堆大小上限,所以不会产生Dump日志。建议您调小JVM堆大小的上限,为容器内其他系统组件预留足够多的内存空间。

- 堆大小和规格内存的参数值可以相同吗? 不可以。因为系统自身组件存在内存开销,例如使用SLS进行日志收集时会占用一小部分的内存空间,所以不能将JVM堆大小设置为和规格内存大小相同的数值,需要为这些系统组件预留足够的内存空间。
- 在JDK 8版本下设置
-XX:MaxRAMPercentage值为整数时报错怎么处理? 这是JDK 8的一个Bug。具体信息,请参见Java Bug Database。例如,在JDK 8u191版本下,设置-XX:MaxRAMPercentage=70,这时JVM会启动报错。

解决方案如下:
- 方式一:设置
-XX:MaxRAMPercentage为70.0。-XX:InitialRAMPercentage或-XX:MinRAMPercentage参数值同样不可设置为整数,需按照浮点数形式来设置。 - 方式二:升级JDK版本至JDK 10及以上版本。
[转帖]JVM参数配置及调优的更多相关文章
- JVM基本配置与调优
JVM基本配置与调优 JVM调优,一般都是针对堆内存配置调优. 如图:堆内存分新生代和老年代,新生代又划分为eden区.from区.to区. 一.区域释义 JVM内存模型,堆内存代划分为新生代和老年代 ...
- JVM典型配置和调优举例
1. 堆设置-Xms: :初始堆大小.-Xmx: :最大堆大小.-XX:NewSize=n: :设置年轻代大小.-XX:NewRatio=n: : :设置年轻代和年老代的比值.如:为 3,表示年轻代与 ...
- JVM性能优化--JVM参数配置,使用JMeter简单测试配合说明参数调优
一.JVM参数配置 1.常见参数配置 -XX:+PrintGC 每次触发GC的时候打印相关日志 -XX:+UseSerialGC 串行回收 -XX:+PrintGCDetails 更详细的GC日志 - ...
- JVM原理讲解和调优
一.什么是JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现 ...
- JVM参数配置 java内存区域
java内存区域 一些基本概念 http://www.importnew.com/18694.html https://www.cnblogs.com/wangyayun/p/6557851.html ...
- 一个性能较好的JVM参数配置
一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...
- 一个性能较好的JVM参数配置(转)
一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...
- JVM参数配置&&命令工具
JVM参数配置 大致方向:JVM调优的目的是保证在一定吞吐量的情况下尽可能的减少GC次数,从而减少系统停顿时间,提高服务质量和效率. 其中减少GC次数的原则: 将新生代转换成老年代的数量降至最少(及时 ...
- JVM底层原理及调优之笔记一
JVM底层原理及调优 1.java虚拟机内存模型(JVM内存模型) 1.堆(-Xms -Xmx -Xmn) java堆,也称为GC堆,是JVM中所管理的内存中最大的一块内存区域,是线程共享的,在JVM ...
- 【CNMP系列】PHP配置和调优
上一节我们说到PHP5.6.30在CentOS7.0下的整个安装过程,http://www.cnblogs.com/riverdubu/p/6428226.html 今天我来和大家讲解一下PHP-FP ...
随机推荐
- JavaFx css样式(三)
JavaFx css样式(三) JavaFX 从入门入门到入土系列 JavaFx css样式,前面我说过它类似html,他有css控制样式,不过最新的css标准并不支持,同时javafx的css样式都 ...
- vue常用函数
this.$router.back(); //回退上一页面
- 华为云MVP高浩:打破AI开发瓶颈,解决数据、算法、算力三大难题
摘要:在高浩看来,大量的数字蓝领人才和AI应用开发人员构成了当前AI行业发展人才之基,这也为高校学生就业初期从事的工作指明了方向,而华为ModelArts平台在教育领域有着天然的数据.算法优势,非常适 ...
- 超详细教程:SpringBoot整合MybatisPlus
摘要:本文为大家带来SpringBoot整合MybatisPlus的教程,实现SpringBoot项目中依赖数据模块进行数据操作,并进行简单测试. 本文分享自华为云社区<SpringBoot整合 ...
- Solon 拉取 maven 包很慢或拉不了,怎么办?
注意:如果在 IDEA 设置里指定了 settings.xml,下面两个方案可能会失效.(或者直接拿"腾讯" 的镜像仓库地址,按自己的习惯配置) 1.可以在项目的 pom.xml ...
- 你好 Java!Solon v1.10.3 发布
相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) qps 高 2- 3 倍. (更高) 运行时内存节省 1/3 ~ 1/2. (更少) 打包 ...
- 只需 3 步,人人都能搭建自己的 chatgpt 微信机器人
大家好,我是徐公,大厂 6 年经验,CSDN 博客专家.最近,ChatGpt 很火,身边的人都在讨论,会不会成为下一个风口,像前几年互联网一样,迎来井喷式的发展. 徐公我最近也是在密切关注,最近,在 ...
- XShell、XFtp免费许可证增强:删除标签限制!
大家好,我是DD! XShell相信大家都不陌生了,作为Windows平台下最强大的SSH工具,是大部分开发者的必备工具.但由于免费许可证的标签限制,有不少开发者会去找破解版使用.虽然功能是可以使用了 ...
- POJ 1236 Network of Schools (连通图 - Garbow 算法)
POJ 1236 Network of Schools 校园网:给定N所学校和网络,目标是分发软件其他学校都可收到,求①所需最少分发学校数:②若任选学校都能收到,最低新增边数. 思路:同一个强连通 ...
- 【每日一题】16.Treepath (LCA + DP)
补题链接:Here 题意总结:寻找有多少条两个点之间偶数路径 看完题,很容易想到在树型中,同一层的节点必然是偶数路径到达,还有就是每隔两层的节点一样可以到达,所以我就理所应当的写了如下代码 using ...