头图

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 adjustment Max. 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


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


ZKNOW甄知科技
1.5k 声望946 粉丝

上海甄知科技有限公司(简称甄知科技)是一家服务管理数字化领先企业,由业界知名的数字化服务综合提供商上海汉得信息技术股份有限公司(股票代码:300170)孵化而成,承袭汉得信息20年的企业信息化服务经验和对...