java程序启动时jvm参数必须置于-jar或主类名之前,否则被当作程序参数传入main方法;-d等参数同理需前置,且spring配置文件、tomcat应用层均不处理jvm参数。

Java命令行启动时JVM参数写在-jar前面
直接用java -jar运行时,所有JVM参数必须放在-jar之前,否则会被当作应用参数传给main方法,JVM完全忽略。
- ✅ 正确:
java -Xms512m -Xmx2g -XX:+UseG1GC -jar app.jar - ❌ 错误:
java -jar app.jar -Xmx2g(-Xmx2g变成程序参数,堆仍按默认值分配) - ⚠️ 注意:
-D参数也属于JVM参数,同样要前置,如-Dspring.profiles.active=prod
OpenShift/K8s容器中不能只信-Xmx
在容器环境里硬写-Xmx12g大概率失效——JVM(尤其JDK 8u191前)读的是宿主机内存,不是容器cgroup限制。结果可能是:你配了12g,实际MaxHeapSize只有2.9g。
- ✅ JDK 8u191+:启用
-XX:+UseContainerSupport(默认已开),改用-XX:MaxRAMPercentage=75.0 - ✅ JDK 8u372+(推荐):直接用
-XX:MaxRAMPercentage=75.0,自动适配cgroups v2 - ❌ 避免混用:
-Xmx和-XX:MaxRAMPercentage同时存在时,后者优先级更高,但行为可能不稳定
Spring Boot的application.properties里不能设JVM参数
application.properties或application.yml只管Spring框架层配置,比如server.port或spring.datasource.url。它对JVM内存、GC策略、线程栈等零影响。
- ⚠️ 常见误解:有人把
-Xms2g写进spring.profiles.default,完全无效 - ✅ 正确做法:通过启动命令、容器
env变量(如JAVA_OPTS)、或K8scommand/args注入 - ? 小技巧:在K8s Deployment中用
env定义JAVA_OPTS,再在command中引用:["sh", "-c", "java $JAVA_OPTS -jar /app.jar"]
Tomcat部署时JVM参数写在catalina.sh/catalina.bat里
Tomcat自身是Java进程,它的JVM参数不通过webapps下的应用控制,而由其启动脚本决定。
- Linux/macOS:编辑
$CATALINA_HOME/bin/catalina.sh,在if [ "$1" = "start" ]前添加:export JAVA_OPTS="-Xms1g -Xmx2g -XX:MetaspaceSize=256m" - Windows:编辑
%CATALINA_HOME%\bin\catalina.bat,加:set JAVA_OPTS=-Xms1g -Xmx2g - ⚠️ 注意:
JAVA_OPTS会被Tomcat内部脚本拼接到java命令最前端,但不会覆盖掉setenv.sh里的同名变量(如果存在)
-jar前后颠倒)、错一层(比如往Spring配置里塞-Xmx)、或错一版(比如在cgroups v2环境还用-XX:+UseCGroupMemoryLimitForHeap),都会导致参数静默失效。真正起作用的永远只有最终执行的那条java命令行。











