docker中的jvm檢測到的是宿主機的內存信息,它無法感知容器的資源上限,這樣可能會導致意外的情況。
-m
參數用於限制容器使用內存的大小,超過大小時會被OOMKilled。
-Xmx: 默認為物理內存的1/4。
4核CPU16G內存的宿主機
java 7
docker run -m 1G -it openjdk:7u181
java -XX:+PrintFlagsFinal -version | grep MaxHeapSize # 結果是 16G / 4 = 4G
java 8
docker run -m 1G -it adoptopenjdk/openjdk8:latest
java -XX:+PrintFlagsFinal -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -version | grep MaxHeapSize # 結果是 1G / 4 = 256M
java 9
docker run -m 1G -it adoptopenjdk/openjdk9:latest java -XX:+PrintFlagsFinal -version | grep MaxHeapSize # 結果是 16G / 4 = 4G java -XX:+PrintFlagsFinal -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -version | grep MaxHeapSize # 結果是 1G / 4 = 256M
java 10
docker run -m 1G -it adoptopenjdk/openjdk10:latest # 給1G jshell -v # 啟動jshell java -XX:+PrintFlagsFinal -version | grep MaxHeapSize # 結果是 1G / 4 = 256M
java5/6/7/8u131-:務必設置內存選項Xmx。
java 8u131+和java 9+ -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap。
java 8u191+ UseContainerSupport默認開啟,backported;java 9暫未backport這個feature。
java10+的UseContainerSupport默認開啟。
Xmx的值可設置為鏡像上限減去150m或200m,根據具體業務考慮。因為棧內存等是不包含在堆內存中的。
cat /sys/fs/cgroup/memory/memory.limit_in_bytes查看容器設置的最大內存。
docker update -m 1024m test動態修改內存大小后,最好重啟容器。
cpu和內存一樣,java10之前的版本感知到的是物理機上的資源。
4核CPU16G內存
java 6/7/8/9
docker run --cpus 1 -m 1G -it adoptopenjdk/openjdk9:latest # 給1核 jshell -J-Xmx512M -v # 啟動jshell Runtime.getRuntime().availableProcessors() # 結果是不是1!!!
java 10
docker run --cpus 1 -m 1G -it adoptopenjdk/openjdk10:latest # 給1核 jshell -J-Xmx512M -v # 啟動jshell Runtime.getRuntime().availableProcessors() # 結果是1
java 10之前:手動設置jvm相關的選項,如:
- ParallelGCThreads
- ConcGCThreads
- G1ConcRefinementThreads
- CICompilerCount / CICompilerCountPerCPU
java 10+:
- UseContainerSupport, 默認開啟