nohup java -server \
-Xms4g \
-Xmx4g \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:InitiatingHeapOccupancyPercent=35 \
-XX:+DisableExplicitGC \
-Duser.timezone=GMT+8 \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/data/logs/app/heapdump.hprof \
-XX:ErrorFile=/data/logs/app/hs_err_pid%p.log \
-verbose:gc \
-Xlog:gc*:time:file=/data/logs/app/gc.log:time \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.rmi.port=12346 \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.ssl=true \
-Djava.rmi.server.hostname=YOUR_SERVER_IP \
-jar /data/apps/boot-demo-0.0.1-SNAPSHOT.jar \
--spring.profiles.active=prod \
--logging.file.name=/data/logs/app/boot-demo.log \
--server.port=8080 > /data/logs/app/nohup.out 2>&1 &
通俗的语言来解释 -XX:InitiatingHeapOccupancyPercent=35 这个 JVM 参数。
简单比喻
想象一下你有一个大仓库(这就是你的 Java 堆内存),用来存放各种物品(这些就是你的 Java 对象)。仓库分为两个区域:一个是新物品区(年轻代),另一个是旧物品区(老年代)。
年轻代:这里放的是新来的、临时的物品。
老年代:这里放的是被认为会长期保存下来的物品。
现在,仓库管理员(G1 垃圾回收器)的任务是保持仓库整洁,移除那些不再需要的物品。为了高效工作,管理员决定在仓库变得太满之前就开始清理。
-XX:InitiatingHeapOccupancyPercent=35 的作用
这个参数就像是告诉管理员:“当仓库里的物品占用了超过 35% 的空间时,你就开始准备清理。”
具体来说:
35%:这是触发清理行动的一个“警戒线”。当仓库里已经有超过 35% 的空间被占用了,管理员就会开始计划并执行一次全面的检查和清理(并发标记周期)。
并发标记周期:这是一个后台进行的过程,管理员会在这个过程中找出哪些物品是垃圾(即不再使用的对象),以便稍后可以安全地移除它们。
为什么设置为 35%?
如果设置得太低(比如 20%),那么管理员可能会频繁地启动清理过程,这样会占用更多的时间和资源。
如果设置得太高(比如 60%),则可能导致仓库突然变得太满,来不及清理,从而导致仓库爆满(相当于应用程序出现内存溢出错误,即 OOM)。
1.JVM 性能调优参数
参数 含义
-Xms4g 启动时分配堆大小为 2GB
-Xmx4g 最大堆大小为 4GB(根据服务器内存调整)
-XX:+UseG1GC 使用 G1 垃圾回收器(适合大堆内存和低延迟)
-XX:MaxGCPauseMillis=200 设置目标 GC 暂停时间上限(毫秒)
-XX:InitiatingHeapOccupancyPercent=35 触发并发 GC 的老年代占用比例
-XX:+DisableExplicitGC 禁用 System.gc() 调用(避免手动 GC 干扰)
2.OOM 处理与诊断
参数 含义
-XX:+HeapDumpOnOutOfMemoryError OOM 时生成堆 dump 文件
-XX:HeapDumpPath=/data/logs/app/heapdump.hprof 指定堆 dump 文件路径
-XX:ErrorFile=/data/logs/app/hs_err_pid%p.log 指定 JVM 崩溃错误日志路径
3. JVM 监控(JMX + JConsole / VisualVM / Prometheus)
参数 含义 -Dcom.sun.management.jmxremote
启用 JMX 远程监控 -Dcom.sun.management.jmxremote.port=12345
JMX 连接端口 -Dcom.sun.management.jmxremote.rmi.port=12346
RMI 端口(用于远程连接) -Dcom.sun.management.jmxremote.authenticate=true
开启身份验证(生产必须) -Dcom.sun.management.jmxremote.ssl=true
开启 SSL 加密(生产必须) -Djava.rmi.server.hostname=YOUR_SERVER_IP
设置公网 IP,用于远程连接
4.日志相关配置
-verbose:gc -Xlog:gc*:time:file=/data/logs/app/gc.log:time 输出详细的 GC 日志
--logging.file.name=/data/logs/app/boot-demo.log Spring Boot 日志输出文件
> /data/logs/app/nohup.out 2>&1 & 将标准输出和错误重定向到 nohup.out,并在后台运行