参考网址
https://www.ipcpu.com/2019/03/java-in-docker-and-kubernetes/
概述
Docker容器利用CGroup对进程使用的资源进行限制,而在容器中的JVM依然会利用宿主机环境的内存大小和CPU核数进行缺省设置,这导致了JVM Heap的错误计算。JVM缺省的GC、JIT编译线程数量取决于宿主机CPU核数。如果我们在一个节点上运行多个Java应用,即使我们设置了CPU的限制,应用之间依然有可能因为GC线程抢占切换,导致应用性能受到影响。 那么我们来看下各个版本JDK如何使用docker的限制。
一、JDK老版本
1、使用环境变量,直接指定JVM堆大小 -e JAVA_OPTIONS=’xMX300m’
2、明确GC和JIT并行线程数目,以避免二者占用过多资源。
-XX:ParallelGCTreads
-XX:CICompilerCount
注意ParallelGCThreads的计算方法:
ParallelGCThreads = (ncpus <= 8) ? ncpus : (8 + ((ncpus - 8) * 5) / 8);
#cpu核数小于等于8,取核数;cpu核数大于8按后面公式计算
二、JDK 8u131+(backported)
使用以下JVM参数,适配docker容器的内存,CPU可能无法获取限制,需要手动设置
-XX:+UnlockExperimentalVMOptions
-XX:+UseCGroupMemoryLimitForHeap
三、 JDK 8u191+(backported)
默认开启了UseContainerSupport,支持容器内部获取CPU和内存限制。
-XX:UseContainerSupport
并增加了ActiveProcessorCount参数指定CPU数量
-XX:ActiveProcessorCount=count
四、 JDK9 、JDK10
不是LTS(长期支持)版本
五、 JDK11+
默认开启了UseContainerSupport,支持容器内部获取CPU和内存限制。
-XX:UseContainerSupport
并增加了ActiveProcessorCount参数指定CPU数量
-XX:ActiveProcessorCount=count