避坑指南
从 java 10 开始,JVM 在分配堆大小的时候,会考虑容器内存限制,而不是主机配置。
对应 JVM 参数为默认开启
java -XX:+UseContainerSupport
可以用过此方法禁用
java -XX:-UseContainerSupport
此参数已向后移植到 Java 8: 文档地址
如果不修改 JVM 内存参数,则默认最大使用总内存的四分之一。
在容器中可以设置一下参数进行更细粒度的内存控制。
-
-XX:InitialRAMPercentage -
-XX:MaxRAMPercentage -
-XX:MinRAMPercentage
值介于 0.0 到 100.0 之间,MaxRAMPercentage 默认值为 25.0。
基于 tomcat 容器下 JVM 配置
可以通过设置容器环境变量 JAVA_OPTS
containers:
- name: java_app
env:
- name: JAVA_OPTS
value: "xxxxxxx"
基于 jdk 容器的 Spring boot 下 JVM 配置
可以通过设置容器环境变量 JAVA_TOOL_OPTIONS
containers:
- name: java_app
env:
- name: JAVA_TOOL_OPTIONS
value: "xxxxxxx"
实战
设置最大容量为总内存的 80%,且使用 k8s 限制容器最大内存为 500M

可见容器正常运行

接下来模拟一个比较苛刻的条件,我们将内存限制为 200M

可以看到容器未能正常启动

查看时间可见为 pod 使用的内存已经超过 k8s 的限制,因此 OOM killed 了

总结 使用 k8s limits 与 jvm -XX:+UseContainerSupport -XX:MaxRAMPercentage=80.0 的配合可以做到对java 程序更加细粒度的控制,无需针对每个程序进行 jvm 内存的计算,仅需控制 k8s limits 即可控制对应程序的内存控制。
参考资料
https://stackoverflow.com/questions/54516988/what-does-usecontainersupport-vm-parameter-do
https://www.oracle.com/java/technologies/javase/8u191-relnotes.html
.jpg)





