一、生产常用参数配置
JAVA_OPTS="-server -Xms3000m -Xmx3000m -Xmn1500m -XX:+UseG1GC -XX:ConcGCThreads=8 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:./g1-gc.log -XX:MaxMetaspaceSize=256m -XX:-UseGCOverheadLimit -XX:+UseCompressedOops -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heap/"
二、常用参数详解
以下表格里面的参数是以G1垃圾收集器为例,列举生产环境常用的参数,大家可根据自身实际情况进行选择。
参数 | 含义 | 说明 |
-server | 服务端模式 | 启动 Server VM(服务器虚拟机),优化应用程序的性能,适用于长期运行的生产环境 |
-Xms | 堆的初始大小 | JVM 启动时堆内存的初始分配大小 |
-Xmx | 堆的最大大小 | 堆内存的最大可用内存 |
-Xmn | 新生代(Young Generation) 的大小 | 新生代用于存放新创建的对象,JVM 会先进行年轻代的垃圾收集 |
-XX:+UseG1GC | 启用 G1垃圾收集器 | 适用于低延迟、高吞吐量的服务端应用。G1 具有低停顿时间的优势,并且能够预测 GC 的时间 |
-XX:ConcGCThreads | 设置并发垃圾收集线程数 | 这是 G1 GC 中进行并行垃圾收集的线程数量。设置合适的值可以加速并行 GC,但也会增加 CPU 的负载 |
-XX:+PrintGCDetails | 打印垃圾收集的详细信息 | 如 GC 的类型、GC 持续时间、回收的内存量等,帮助分析垃圾回收的行为和性能 |
-XX:+PrintGCTimeStamps | 打印垃圾回收的时间戳信息 | 帮助分析垃圾回收发生的时间点 |
-Xloggc | 将 GC 日志输出到文件中 | 可以通过分析日志来优化垃圾收集的配置 |
-XX:MaxMetaspaceSize | 设置 Metaspace(类元数据空间)的最大大小 | Metaspace 存储了 JVM 加载的类的元数据。过大可能导致内存使用过高,过小可能导致类加载失败 |
-XX:-UseGCOverheadLimit | 禁用 GC 开销限制 | 默认情况下,如果 JVM 发现长时间进行 GC 并且回收的内存很少,JVM 会抛出 java.lang.OutOfMemoryError 。通过禁用该选项,可以避免出现 GC overhead limit exceeded 错误 |
-XX:+UseCompressedOops | 启用 Compressed Oops(压缩对象指针) | 在 64 位的 JVM 中,对象的引用通常是 8 字节的指针,启用 Compressed Oops 可以将其压缩为 4 字节,节省内存空间,提供性能,通常对于堆较大的应用更有意义 |
-XX:+HeapDumpOnOutOfMemoryError | 当发生 OutOfMemoryError 时,自动生成堆转储(Heap Dump) | 可以用来分析内存泄漏和内存问题。堆转储文件可以通过工具如 Eclipse MAT 或 jvisualvm 进行分析 |
-XX:HeapDumpPath | 设置堆转储文件的存放路径 | 指定堆转储文件保存的目录 |
四、可选参数
参数 | 含义 | 说明 |
-XX:SurvivorRatio | 设置Eden区与Survivor区的比例(默认8:2) | 可以影响垃圾收集的频率和停顿时间。较大的Survivor区可以减少Minor GC的次数,但每次GC的停顿时间可能会增加;较小的Survivor区则相反 |
-XX:NewRatio | 参数用于设置新生代(Young Generation)与老年代(Old Generation)的比例(默认1:2) | 对于年轻代对象较多的应用,增大新生代的比例可以减少Minor GC的频率;而对于老年代对象较多的应用,减小新生代的比例可以更频繁地进行Minor GC,从而减少Full GC的发生。 |
-XX:+UseStringDeduplication | 启用字符串去重 | 可以减少内存占用 |
-XX:+DisableExplicitGC | 禁用显式调用System.gc(), | 避免不必要的GC触发 |
-XX:+AlwaysPreTouch | 在启动时预先触碰所有页面 | 减少运行时的延迟 |
-XX:+ScavengeBeforeFullGC | 在Full GC之前先进行一次Young GC | 减少Full GC的频率和停顿时间 |
-XX:+CMSClassUnloadingEnabled: | 启用CMS垃圾收集器的类卸载功能 | 适用于老年代较大的应用 |
-XX:+PrintCommandLineFlags | 打印命令行的参数 | 帮助开发者了解JVM启动时的完整参数设置 |
三、JVM调优建议
对于生产环境中常见的 JVM 调优参数,除了上面的设置外,还可以考虑以下优化
1.内存管理优化
-
堆内存大小:根据应用的实际需求和可用物理内存来调整
-Xms
和-Xmx
的值。如果应用需要更多内存,可以适当增加这些值;如果内存资源有限,则需要谨慎设置以避免OOM(Out of Memory)错误。 -
新生代大小 (
-Xmn
):根据应用的对象创建情况调整新生代大小。一般来说,较大的新生代可以减少年轻代的垃圾收集次数,减少全量 GC 的发生频率,但同时会增加老年代 GC 的发生频率。常见的建议是:新生代大小设置为堆总大小的 1/3 到 1/2。例如,如果总堆大小是3000MB,那么新生代可以设置为1000MB左右。 -
老年代大小:可以通过调整
-XX:SurvivorRatio
或-XX:NewRatio
来优化老年代和新生代之间的内存分配比例。
2.垃圾回收优化
-
垃圾回收日志:建议添加更多的 GC 日志参数来帮助你了解垃圾收集的行为和性能瓶颈,使用工具如GCViewer、GCEasy等来可视化和分析GC日志。例如:
-XX:+PrintGCApplicationStoppedTime
:打印应用停止时间的日志,帮助分析 GC 停顿的影响。-XX:+PrintGCDateStamps
:在 GC 日志中打印时间戳,有助于分析 GC 间隔。
-
G1GC 参数优化:可以进一步调整 G1GC 的参数来优化 GC 性能,具体参数根据应用场景来设置。
-XX:MaxGCPauseMillis=200
:设置 G1 GC 的最大暂停时间为 200ms,G1 会尽量保证垃圾回收的暂停时间不超过这个值。-XX:G1HeapRegionSize=16M
:设置 G1 GC 中堆区的大小,适用于更大的堆,帮助提高 G1 的回收效率。
3.堆外内存和元空间
-
元空间大小:
-XX:MaxMetaspaceSize
如果应用加载了大量的类或者使用了动态代理等技术,可能需要适当增加这个值,防止在类加载过程中因为元空间内存不足而抛出OutOfMemoryError。
-
Direct Memory:对于需要使用大量直接内存的应用(例如 NIO),可以通过设置
-XX:MaxDirectMemorySize
限制直接内存的大小。
4.其他调优参数
-
并发GC线程数:
-XX:ConcGCThreads=8
表示使用8个并发GC线程。这个值可以根据实际CPU核心数和应用负载进行调整。一般来说,可以设置为CPU核心数的一半或稍多一些。 -
Thread Stack Size:
-Xss
设置线程栈大小,默认情况下,每个线程分配 1MB 的栈空间。对于高并发应用,如果线程栈较大,可以考虑减小-Xss
参数的值,以减少每个线程占用的内存。 -
JVM 垃圾回收的并行度:
-XX:ParallelGCThreads=8
:针对于ParallelGC,
设置并行 GC 线程数,适用于多核 CPU 系统,调优时可以增加此值来加速 GC。
四、总结
具体的调优大家还需要结合实际的应用负载和运行环境进行实际情况调整,下面是调优的一些常见方向,这些设置和调优参数在生产环境中非常重要,帮助 JVM 运行时更加稳定和高效。
- 堆内存调优:根据应用的内存需求,调整堆大小、年轻代和老年代的比例。
- GC 选择和调优:根据应用对延迟和吞吐量的需求,选择合适的 GC,并调整相关参数来减少 GC 停顿。
- 内存泄漏检测:启用堆转储以便在内存溢出时进行分析,减少内存泄漏的风险。
- 日志分析:通过 GC 日志帮助开发人员识别性能瓶颈,尤其是垃圾回收方面的影响。