Java容器启动参数必须在ENTRYPOINT中显式声明,正确做法是将JVM参数(如-Xms512m、-Xmx1g)写入Deployment的args字段,保持ENTRYPOINT为["java", "-jar", "app.jar"]结构;若错误写入command字段导致缺失"java"前缀,容器将报“executable file not found”。

Java容器启动参数必须在ENTRYPOINT里显式声明
直接在 kubectl run 或 Deployment 的 command 字段里覆盖整个启动命令,会导致 JVM 启动逻辑丢失(比如 Spring Boot 的 fat jar 解包机制),正确做法是只替换 args,让 ENTRYPOINT 保持为 ["java", "-jar", "app.jar"] 结构,再把 JVM 参数塞进 args。
常见错误是把 -Xmx 写在 command 里,结果变成 ["-Xmx1g", "-jar", "app.jar"] —— 缺少 java 命令前缀,容器直接报 executable file not found。
- ✅ 正确:在 Deployment YAML 的
containers[].args中传参,例如:["-Xms512m", "-Xmx1g", "-XX:+UseContainerSupport", "-jar", "app.jar"] - ❌ 错误:在
command中写["-Xmx1g", "-jar", "app.jar"](没 java) - ⚠️ 注意:
args会完全覆盖 Dockerfile 中的默认ENTRYPOINT的参数部分,但不会动命令本身;而command会同时覆盖命令和参数
UseContainerSupport 和 ActiveProcessorCount 必须配对使用
JDK8u191+ 默认启用 -XX:+UseContainerSupport,但它只解决内存识别问题;CPU 核心数仍可能读错——尤其当 Kubernetes 设置了 cpu.limit=2 但 cpu.request=1 时,JVM 可能看到 2 个核,却只被调度到 1 个上运行,导致 GC 线程或 ForkJoinPool 过度并发、争抢资源。
所以不能只开 UseContainerSupport,还得强制指定处理器数:
- 用
Runtime.getRuntime().availableProcessors()验证实际值 - 在
args中加-XX:ActiveProcessorCount=2,该值应等于resources.limits.cpu(单位是核心数,不是毫核) - 若
limits.cpu: "1500m",对应ActiveProcessorCount=1(因为
堆内存设置要和容器 memory limits 对齐
JVM 堆上限(-Xmx)不能等于容器 memory.limit,否则 Native Memory(如 Metaspace、Direct Buffer、线程栈)没空间,容易 OOMKilled。建议留出 20%~30% 余量。
例如容器限制 memory: "4Gi",则 -Xmx 最好设为 3g 或 3200m;同时务必把 -Xms 设为相同值,避免堆动态扩容引发 GC 波动。
- 别用
-Xmx4g—— 容器 cgroup 内存超限时会被 kubelet 杀掉,且不走 JVM OOM 流程 - 推荐通过环境变量注入,比如在 Deployment 中设
env: [{name: JAVA_OPTS, value: "-Xms3g -Xmx3g -XX:+UseContainerSupport"}],然后args改为["$(JAVA_OPTS)", "-jar", "app.jar"](需镜像支持 shell 展开) - 若镜像用的是
exec模式 ENTRYPOINT(即 JSON 数组),则无法展开变量,必须硬编码或改用 shell 形式 ENTRYPOINT
Spring Boot 应用优先用 --spring.profiles.active 而非 JVM 参数传配置
Spring Boot 的 profile、server.port、logging.level 等属于应用层配置,不该塞进 JVM 参数。它们应该通过 args 以应用参数形式传入,和 -jar 在同一层级。
例如:["-Xmx1g", "-jar", "app.jar", "--spring.profiles.active=prod", "--server.port=8081"]。注意:JVM 参数必须在 -jar 前,应用参数必须在 -jar 后,顺序错了会被忽略。
- 错例:
["-jar", "app.jar", "-Dspring.profiles.active=prod"]——-D在-jar后无效 - 错例:
["-Dspring.profiles.active=prod", "-jar", "app.jar"]—— 这个能生效,但属于旧式 System Property 方式,不如--xxx语义清晰、支持类型转换 - 敏感配置(如数据库密码)应走
Secret挂载或环境变量,避免出现在 args 日志里
ActiveProcessorCount 和堆内存余量,这两个点线上出问题时往往表现为 CPU 利用率虚高或莫名 OOMKilled。


















