JVM 的内存参数众多,但是在实际应用中主要关注堆内存的大小设置及堆内存中新生代和老年代的大小设置,下面看一个简单的 JVM 启动参数设置案例:
java -server
-Xms3g -Xmx3g
-XX:NewSize=1g
-XX:MetaspaceSize=128m
-XX:NewRatio=3
-XX:SurvivorRatio=8
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=dump.log -jar start.jar
-Xms -Xmx:-Xms 表示初始堆大小,-Xmx 表示最大堆大小。一般将 Xms 和 Xmx 设置为相同的值,避免垃圾回收后 JVM 重新分配堆内存大小而引起内存震荡,影响性能。可将堆内存的大小简单理解为 JVM 在运行过程中可用到的总内存大小。
-XX:NewSize:-XX:NewSize=1g 表示设置新生代的大小为 1GB,一般建议设置为总堆内存的 1/3
-XX:MetaspaceSize:表示元空间的大小为 128MB,当要加载的类库过多时,可以适当调高这个值
-XX:NewRatio:-XX:NewRatio=3 表示设置新生代与老年代的比值为 1:3,因此新生代占整个堆栈的 1/4,老年代占整个堆内存的 3/4
-XX:SurvivorRatio: -XX:SurvivorRatio=8 表示 Eden 区和两个 Survivor 区的比值为 8:1,即 Eden:SurvivorTo=8:1、Eden:SurvivorFrom=8:1。最终的结果是 Eden:SurvivorTo:SurvivorFrom=8:1:1
-XX:+UseParNewGC XX:+UseConcMarkSweepGC:垃圾回收器设置 -XX:+UseParNewGC 表示设置年轻代垃圾回收器为 ParNew 垃圾回收器。-XX:+UseConcMarkSweepGC 表示设置老年代垃圾回收器为 CMS 垃圾回收器
-OOM异常诊断设置:XX:HeapDumpOnOutOfMemoryError 表示当发生 OOM 时转储堆到文件。XX:HeapDumpPath 表示堆的转储文件路径地址。这两个参数结合起来,可以在程序出现 OOM 时及时将堆信息打印出来,方便后续分析故障
在进行 JVM 参数设置时需要重点关注垃圾回收器的设置和 JVM 内存的设置。接下以在一个 8GB 的服务器上独立运行一个名为 start.jar 的 Netty 应用服务为例,介绍内存设置的流程
-XX:MaxDirectMemorySize-2g
设置可用的最大堆外内存为 2GB。在使用过程中会按需分配足够的内存给直接内存,但最大不超过 2GB-Xm3g -Xmx3g
XX:MetaspaceSize=128m
设置元空间大小为 128MB。将剩余的少部分内存留给操作系统或者其他应用程序使用-XX:+UserConcMarkSweepGC
可设置老年代使用 CMS 垃圾回收器,新生代使用默认的 ParNew 垃圾回收器。使用 -XX:+UseG1GC
可设置使用 G1 垃圾回收器具体配置如下:
java -server
-XX:MaxDirectMemorySize=2g # 直接内存的大小为 2GB
-Xms3g -Xmx3g # Java 堆内存的大小为 3GB
-XX:NewSize=1g # 新生代的大小为 1GB
-XX:MetaspaceSize=128m # 元空间为 128MB
-XX:+UseParNewGC -XX:+UseConcMarkSweepGC # 新生代使用 ParNewGC,老年代使用 CMS
-xx:+HeapDumponCutOfMemoryError # 在发生 OOM 时打印日志
-XX:HeapDumpPath=dump.log # OOM 日志存储地址
-XX:+PrintGC # 输出 GC 日志
-XX:+PrintGCDetails # 输出 GC 的详细日志
-XX:+PrintGCDatestamps # 输出 GC 的时间戳
-XX:+PrintHeapAtGC # JVM 在执行 GC 操作的前后打印堆的信息
-Xlogge:../gc/gc.log # GC日志的输出地址
-jar start.jar
另外,需要注意不同 JVM 版本的配置参数不同,比如 -XX:PermSizeXX
和 -XX:MaxPermsize
分别表示永久代的初始化大小和永久代的最大大小。但是在 Java8 已经没有永久代了,因此也不存在该配置参数。