Preface
Although the containerization of Java applications better solves the portability problem, there are also some unfriendly situations. For example, the low version of the JDK (lower than Java 8u131) does not recognize the CGroup resource limit. This will cause the JVM to read all the CPU and memory of the host, and once the container uses more resources than the limit, it will be killed by docker.
In kubernetes, we will display the configuration of the CPU, memory request and limit in the yaml file. We hope that the JVM process in the container can automatically recognize the CGroup resource limit, obtain the correct memory and CPU information, and adjust it dynamically.
JVM parameter configuration
The following operations are all performed on a 4C 16G server.
Version lower than 8u131
The JVM with a JDK version lower than 8u131 will not automatically recognize the CGroup resource limit. You need to manually set the initial heap size and maximum heap size, otherwise the default value will be set according to the total memory of the host:
- Configure the maximum heap size
-Xmx
, the default value: 1/4 of the memory - Configure the initial heap size
-Xms
, the default value: 1/64 of the memory
JVM parameters are not configured
You can see Max. Heap Size (Estimated): 3.48G
, which failed to correctly identify the CGroup resource limit
$ docker run --rm -m 2GB openjdk:8u121-alpine java -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 3.48G
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
openjdk version "1.8.0_121"
OpenJDK Runtime Environment (IcedTea 3.3.0) (Alpine 8.121.13-r0)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)
Configure JVM parameters
After configuring -Xmx
and -Xms
, we can achieve the results we want
$ docker run --rm -m 2GB openjdk:8u121-alpine java -XshowSettings:vm -Xmx2000m -Xms2000m -version
VM settings:
Min. Heap Size: 1.95G
Max. Heap Size: 1.95G
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
openjdk version "1.8.0_121"
OpenJDK Runtime Environment (IcedTea 3.3.0) (Alpine 8.121.13-r0)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)
8u131 and above
From 8u131 version began to support UseCGroupMemoryLimitForHeap
and MaxRAMFraction
these two options, with CGroupMemory
size as the JVM heap size, MAXRAMFraction
is used to control the amount of memory actually available, for example set to 1, then that is CGroupMemoryLimit
all set to talk 2 half 3 is 1/3, and so on
| MaxRAMFraction value | heap accounted | container 1G memory = | container 2G memory = | container 4G memory = | container 8G memory = | container 16G memory = | |: —-:|:—-|:—-:|:—-|:—-:|:—-|:—-:|:—-|:—-:|:—-|:—-:|: —-|:—-:|:—-| |1|≈90%|910.50M|1.78G|3.56G|7.11G|14.22G| |2|≈50%|455.50M|910.50M|1.78G| 3.56G|7.11G| |3|≈33%|304.00M|608.00M|1.19G|2.37G|4.74G| |4|≈25%|228.00M|455.50M|910.50M|1.78G|3.56G|
JVM parameters are not configured
You can see Max. Heap Size (Estimated): 3.48G
, which failed to correctly identify the CGroup resource limit
$ docker run --rm -m 2GB openjdk:8u131-alpine java -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 3.48G
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (IcedTea 3.4.0) (Alpine 8.131.11-r2)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)
Configure JVM parameters
After configuring -XX:+UnlockExperimentalVMOptions
, -XX:+UseCGroupMemoryLimitForHeap
and -XX:MaxRAMFraction=1
, we can achieve the results we want
$ docker run --rm -m 2GB openjdk:8u131-alpine java -XshowSettings:vm -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -version
VM settings:
Max. Heap Size (Estimated): 1.78G
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (IcedTea 3.4.0) (Alpine 8.131.11-r2)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)
8u191 and above
UseContainerSupport
option on java10+ has been introduced, and it is enabled by default and does not need to be set. At the same time, UseCGroupMemoryLimitForHeap
is deprecated and it is not recommended to continue to use it. At the same time, you can control the memory ratio used by the JVM more delicately through parameters such as -XX:InitialRAMPercentage
, -XX:MaxRAMPercentage
, and -XX:MinRAMPercentage
For example, some Java programs will call external processes and apply for Native Memory when they are running. Therefore, even if the Java program is running in a container, some memory must be reserved for the system. Therefore, -XX:MaxRAMPercentage
cannot be configured too large.
JVM parameters are not configured
You can see that the CGroup resource limit can be correctly identified without adding any JVM parameters
$ docker run --rm -m 2GB openjdk:8u191-alpine java -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 455.50M
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-r0)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
Configure JVM parameters
- Use
-XX:MaxRAMFraction
parameter adjustmentMax. Heap Size
size`
Console $ RUN -rm Docker -m 2GB OpenJDK: 8u191 Java-Alpine -XX: MaxRAMFraction = -XshowSettings. 1: VM -version
VM settings: Max. Heap Size (Estimated): 1.78G Ergonomics Machine Class: server Using VM: OpenJDK 64-Bit Server VM
openjdk version “1.8.0_191” OpenJDK Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-r0) OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
* 使用 `-XX:InitialRAMPercentage`、`-XX:MaxRAMPercentage`、`-XX:MinRAMPercentage` 参数更加细腻的控制 JVM 使用的内存比率
```console
$ docker run --rm -m 2GB openjdk:8u191-alpine java -XX:InitialRAMPercentage=40.0 -XX:MaxRAMPercentage=90.0 -XX:MinRAMPercentage=50.0 -XshowSettings:vm -version
VM settings:
Max. Heap Size (Estimated): 1.60G
Ergonomics Machine Class: server
Using VM: OpenJDK 64-Bit Server VM
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-r0)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
Reference
- http://www.51gjie.com/java/551.html
- https://zhuanlan.zhihu.com/p/140849800
- https://my.oschina.net/neverforget/blog/4779579
- https://sevenyu.top/2019/04/01/java-resources-limit.html
- https://qingmu.io/2018/12/17/How-to-securely-limit-JVM-resources-in-a-container/
This article was originally created by the Toothfish technical team, please indicate the source for reprinting: official website
about pig tooth fish
The Choerodon full-scenario performance platform provides systematic methodology and collaboration, testing, DevOps and container tools to help companies pull through the requirements, design, development, deployment, testing and operation processes, and improve management efficiency and quality in one stop. From team collaboration to DevOps tool chain, from platform tools to systemic methodology, Pigtooth fully meets the needs of collaborative management and engineering efficiency, runs through the entire end-to-end process, and helps the team to be faster, stronger and more stable. here to try the pig tooth fish
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。