preface

While containerizing Java applications better addresses portability issues, there are some unfriendly situations, such as the fact that older JDK versions (lower than Java 8U131) do not recognize CGroup resource limits. This will cause the JVM to read all the CPU and memory of the host machine, and the container will be killed by the Docker if its resource usage exceeds the limit.

In Kubernetes, we show that CPU, memory requests, and limits are configured in yamL files, and we want the JVM process in the container to automatically recognize CGroup resource limits and get the correct memory and CPU information to adjust dynamically on its own.

JVM Parameter Configuration

The following operations are performed on a 4C 16G server.

Version is earlier than 8U131

JVMS with JDK versions lower than 8U131 will not automatically recognize CGroup resource limits. You will need to manually set the initial heap size and maximum heap size, otherwise the default values will be set to the full memory of the host machine:

  • Configure the maximum heap size-XmxDefault value: 1/4 of memory
  • Configure the initial heap size-XmsDefault value: 1/64 of memory

No JVM parameters are configured

Max. Heap Size (Estimated): 3.48G, cannot 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 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)Copy the code

Configuring JVM Parameters

Configuring -xmx and -xms gives us the desired result

$ docker run --rm -m 2GB openjdk:8u121-alpine java -XshowSettings:vm -Xmx2000m -Xms2000m -version VM settings: Heap Size: 1.95g Max. Heap Size: 1.95g Ergonomics Machine Class: Server Using 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)Copy the code

8U131 and later versions

Since version 8 u131 support UseCGroupMemoryLimitForHeap and MaxRAMFraction these two options, use CGroupMemory size as the JVM heap size, MAXRAMFraction is used to control the actual amount of memory that is available, such as 1 for CGroupMemoryLimit, 2 for half, 3 for 1/3, and so on

| | value of MaxRAMFraction heap of memory = 1 g | | container vessel memory = 2 g memory = 4 g | | container vessel memory = 8 g memory = 16 g | | container : | — – | — – | : – : : | — – | : – : : | — – | : – : : | — – | : – : : | — – | : – : : | — – | : – : | : – | | | 1 material 90% 910.50 M | | | | 3.56 G 1.78 G 7.11 G 14.22 G | | | 2 | material 50% 455.50 M 910.50 M | | | | | 3.56 G 1.78 G 7.11 G | | 3 | material 33% 304.00 M 608.00 M | | | | | | 2.37 G 4.74 G 1.19 G | | 4 material 25% | | 228.00 M, 455.50 M 910.50 M | | | | 3.56 G 1.78 G

No JVM parameters are configured

Max. Heap Size (Estimated): 3.48G, cannot 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 Runtime Environment (IcedTea 3.4.0) (Alpine 8.131.11-R2) OpenJDK 64-bit Server VM (build 25.131-b11, mixed mode)Copy the code

Configuring JVM Parameters

Configuration – XX: + UnlockExperimentalVMOptions, XX: XX: + UseCGroupMemoryLimitForHeap and after MaxRAMFraction = 1 can get 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 Runtime Environment (IcedTea 3.4.0) (Alpine 8.131.11-R2) OpenJDK 64-bit Server VM (build 25.131-b11, mixed mode)Copy the code

8U191 and later versions

The UseContainerSupport option on Java10 + is introduced starting with 8U191 and is enabled by default without setting. At the same time UseCGroupMemoryLimitForHeap this is deprecated, continue to use is not recommended. In addition, parameters -xx :InitialRAMPercentage, -xx :MaxRAMPercentage, and -xx :MinRAMPercentage can be used to control the memory ratio used by the JVM. For example, some Java programs call external processes and apply for Native Memory when they run. Therefore, even if Java programs are run in containers, some Memory must be reserved for the system. Therefore, the value of -xx :MaxRAMPercentage cannot be too large.

No JVM parameters are configured

You can see that CGroup resource limits are 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.50 Ergonomics Machine Class: Server Using VM: OpenJDK Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-r0) OpenJDK 64-bit Server VM (build 25.191-B12, Mixed mode)Copy the code

Configuring JVM Parameters

  • use-XX:MaxRAMFractionParameter adjustmentMax. Heap SizeConsole $docker run -rm -m 2GB OpenJDK :8u191-alpine Java -xx :MaxRAMFraction=1 -xshowSettings: vM-version

VM settings: Max. Heap Size (Estimated): 1.78G Ergonomics Machine Class: server Using VM: OpenJDK 64-Bit Server VM

Openjdk Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-R0) OpenJDK 64-bit Server VM 25.191 b12 (build, mixed mode)

* Use the '-xx :InitialRAMPercentage', '-xx :MaxRAMPercentage', and '-xx :MinRAMPercentage' parameters to more subtly control the memory ratio used by the 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 Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-r0) OpenJDK 64-bit Server VM (build 25.191-B12, Mixed mode)Copy the code

The resources

  • www.51gjie.com/java/551.ht…
  • zhuanlan.zhihu.com/p/140849800
  • My.oschina.net/neverforget…
  • Sevenyu. Top / 2019/04/01 /…
  • Qingmu. IO / 2018/12/17 /…

This article was originally written by the toothfish technical team.The official website of toothfish

About the toothfish

Choerodon’s full-scene performance platform provides systematic methodology and collaboration, testing, DevOps and container tools to help enterprises streamline their requirements, design, development, deployment, testing and operations processes to improve management efficiency and quality in a one-stop shop. From team collaboration to DevOps tool chain, from platform tools to systematic methodology, toothfish fully meets the needs of collaborative management and engineering efficiency, running through the whole end-to-end process, helping team efficiency become faster, stronger and more stable. Poke here to try the toothfish