15. JVM调优的参数设置
1. JVM介绍和运行流程
2.JVM程序计数器
3.JAVA堆和JVM内存结构
4.虚拟机栈
5.JVM的方法区
6.JVM直接内存
7. JVM类加载器与双亲委派模型
8. JVM类装载的执行过程-CSDN博客
9. JVM垃圾回收-CSDN博客
10. 垃圾回收的算法-CSDN博客
11. JVM中的分代回收-CSDN博客
12. JVM的垃圾回收器-CSDN博客
13. G1垃圾回收器-CSDN博客
14. 垃圾回收的引用区别-CSDN博客
15. JVM调优的参数设置-CSDN博客
16. JVM调优工具-CSDN博客
1. JVM调优的参数
对于JM调优,主要就是调整年轻代、老年代、元空间的内存空间大小及使用的垃圾回收器类型。
主要说以下几个方面:
- 设置堆空间大小
- 虚拟机栈的设置
- 年轻代中Eden区和两个Survivor区的大小比例
- 年轻代晋升老年代阀值
- 设置垃圾回收收集器
1. 设置堆空间大小
设置堆的初始大小和最大大小,为了防止垃圾收集器在初始大小、最大大小之间收缩堆而产生额外的时间,通常把最大、初始大小设置为相同的值。
核心参数:
-
-Xms
:初始堆大小(建议和-Xmx
相同,避免动态扩容的开销) -
-Xmx
:最大堆大小(不超过物理内存的80%)
示例:
-Xms:1024
-Xms:1024k
-Xms:1024m
-Xms :lg
不指定单位默认为字节
指定单位,按照指定的单位设置
注意事项:
- 生产环境建议
-Xms
和-Xmx
设为相同值,避免运行时堆内存波动。 - 最大大小的默认值是物理内存的1/4,初始大小是物理内存的1/64
- 堆太小,可能会频繁的导致年轻代和老年代的垃圾回收,会产生stw,暂停用户线程
- 堆内存大肯定是好的,存在风险,假如发生了fullgc,它会扫描整个堆空间,暂停用户线程的时间长
- 设置参考推荐:尽量大,也要考察一下当前计算机其他程序的内存使用情况
2. 虚拟机栈的设置
每个线程默认会开启1M的内存,用于存放栈帧、调用参数、局部变量等,但一般256K就够用。通常减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统。
核心参数:
-
-Xss
:每个线程的栈大小(默认1MB,Linux/x64)
注意事项:
-
栈大小影响线程数量(栈越小,可创建的线程越多)。
-
如果程序递归调用很深或方法调用链过长,可能需要增大
-Xss
,否则会抛出StackOverflowError
。
3. 年轻代中Eden区和Survivor区的比例
设置年轻代中Eden区和两个Survivor区的大小比例。该值如果不设置,则默认比例为8:1:1。
通过增大Eden区的大小来减少YGC发生的次数,但有时我们发现,虽然次数减少了,但Eden区满的时候,由于占用的空间较大,导致释放缓慢,此时STW的时间较长,因此需要按照程序情况去调优。
核心参数:
-
-XX:SurvivorRatio
:Eden区与一个Survivor区的比例(默认8
,即Eden:S0:S1=8:1:1
)
注意事项:
-
增大
SurvivorRatio
会让Eden区更大,减少Minor GC次数,但可能导致Survivor区溢出。 -
如果对象存活率高,可以适当减小比例(如
-XX:SurvivorRatio=4
)。
4. 年轻代晋升老年代的阈值
核心参数:
-
-XX:MaxTenuringThreshold
:对象经历Minor GC的最大次数后晋升老年代(默认15
)
注意事项:
-
如果应用产生大量短期对象,可以降低阈值(如
5
),避免Survivor区频繁复制。 -
如果对象存活时间长,可以增大阈值(如
10
),减少老年代压力。
5. 设置垃圾回收器
常用回收器及参数:
回收器 | 参数 | 适用场景 |
---|---|---|
Serial GC | -XX:+UseSerialGC | 单核CPU或小型应用 |
Parallel GC | -XX:+UseParallelGC | 吞吐量优先(JDK8默认) |
CMS GC | -XX:+UseConcMarkSweepGC | 低延迟(JDK8推荐,已废弃) |
G1 GC | -XX:+UseG1GC | 平衡吞吐和延迟(JDK9+默认) |
ZGC | -XX:+UseZGC | 超大堆低延迟(JDK11+) |
注意事项:
-
JDK8建议用
G1
或CMS
(但CMS已废弃)。 -
JDK11+建议用
G1
或ZGC
(ZGC适合堆>4GB的场景)。