jvm · 2024-11-25 0

容器环境设置 java 堆

准备

启动容器,限制大小为 4G
宿主机内存 32G

docker run -itd --name ubuntu_1 -m 4G --cap-add CAP_SYS_PTRACE ubuntu:20.04

一、8u121

默认:

  • InitialRAMFraction=64
  • MinRAMFraction=2
  • MaxRAMFraction=4
root@eb3a8b28b6d2:/opt/jdk1.8.0_121/bin# ./java -XX:+PrintFlagsFinal -version | grep -E RAM
    uintx DefaultMaxRAMFraction                     = 4                                   {product}
    uintx InitialRAMFraction                        = 64                                  {product}
 uint64_t MaxRAM                                    = 137438953472                        {pd product}
    uintx MaxRAMFraction                            = 4                                   {product}
    uintx MinRAMFraction                            = 2                                   {product}

1.默认配置

默认占用物理内存的 1/4 (32G*1/4=8G)

root@eb3a8b28b6d2:/opt/jdk1.8.0_121/bin# ./java -jar /opt/app.jar
  • InitialHeapSize=524288000 (32G*1/64=0.5G)
  • MaxHeapSize=8378122240 (32G*1/4=8G)
root@eb3a8b28b6d2:/opt/jdk1.8.0_121/bin# ./jinfo -flags 1119
JVM version is 25.121-b13
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=524288000 -XX:MaxHeapSize=8378122240 -XX:MaxNewSize=2792357888 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=174587904 -XX:OldSize=349700096 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line: 

2.设置 MaxRAMFraction

占用物理内存的 100% (32G)

root@eb3a8b28b6d2:/opt/jdk1.8.0_121/bin# ./java -XX:InitialRAMFraction=4 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=1 -jar /opt/app.jar
  • InitialHeapSize=524288000 (32G*1/4=8G)
  • MaxHeapSize=32210157568 (32G)
  • InitialRAMFraction=4
  • MinRAMFraction=2
  • MaxRAMFraction=1
root@eb3a8b28b6d2:/opt/jdk1.8.0_121/bin# ./jinfo -flags 279
JVM version is 25.121-b13
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=8378122240 -XX:InitialRAMFraction=4 -XX:MaxHeapSize=32210157568 -XX:MaxNewSize=10736369664 -XX:MaxRAMFraction=1 -XX:MinHeapDeltaBytes=524288 -XX:MinRAMFraction=2 -XX:NewSize=2792357888 -XX:OldSize=5585764352 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -XX:InitialRAMFraction=4 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=1

3.设置 UseCGroupMemoryLimitForHeap

jdk8u121 不支持 UseCGroupMemoryLimitForHeap

root@eb3a8b28b6d2:/opt/jdk1.8.0_121/bin# ./java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:InitialRAMFraction=4 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=1 -jar /opt/app.jar
Unrecognized VM option 'UseCGroupMemoryLimitForHeap'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

二、8u131

默认:

  • InitialRAMFraction=64
  • MinRAMFraction=2
  • MaxRAMFraction=4
root@eb3a8b28b6d2:/opt/jdk1.8.0_131/bin# ./java -XX:+PrintFlagsFinal -version | grep -E RAM
    uintx DefaultMaxRAMFraction                     = 4                                   {product}
    uintx InitialRAMFraction                        = 64                                  {product}
 uint64_t MaxRAM                                    = 137438953472                        {pd product}
    uintx MaxRAMFraction                            = 4                                   {product}
    uintx MinRAMFraction                            = 2                                   {product}

1.默认配置

同 jdk8u121

2.设置 MaxRAMFraction

同 jdk8u121

3.设置 UseCGroupMemoryLimitForHeap

占用容器内存的 100% (4G)

root@eb3a8b28b6d2:/opt/jdk1.8.0_131/bin# ./java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:InitialRAMFraction=4 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=1 -jar /opt/app.jar
  • InitialHeapSize=1073741824 (4G*1/4=1G)
  • MaxHeapSize=4294967296 (4G)
  • UnlockExperimentalVMOptions
  • UseCGroupMemoryLimitForHeap
  • InitialRAMFraction=4
  • MinRAMFraction=2
  • MaxRAMFraction=1
root@eb3a8b28b6d2:/opt/jdk1.8.0_131/bin# ./jinfo -flags 725
JVM version is 25.131-b11
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=1073741824 -XX:InitialRAMFraction=4 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431306240 -XX:MaxRAMFraction=1 -XX:MinHeapDeltaBytes=524288 -XX:MinRAMFraction=2 -XX:NewSize=357564416 -XX:OldSize=716177408 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:InitialRAMFraction=4 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=1

三、8u191

默认
InitialRAMFraction=64
MinRAMFraction=2
MaxRAMFraction=4
InitialRAMPercentage=1.562500
MinRAMPercentage=50.000000
MaxRAMPercentage=25.000000

其中 1/64=1.562500 1/2=50.000000 1/4=25.000000

root@eb3a8b28b6d2:/opt/jdk1.8.0_191/bin# ./java -XX:+PrintFlagsFinal -version | grep -E RAM
    uintx DefaultMaxRAMFraction                     = 4                                   {product}
    uintx InitialRAMFraction                        = 64                                  {product}
   double InitialRAMPercentage                      = 1.562500                            {product}
 uint64_t MaxRAM                                    = 137438953472                        {pd product}
    uintx MaxRAMFraction                            = 4                                   {product}
   double MaxRAMPercentage                          = 25.000000                           {product}
    uintx MinRAMFraction                            = 2                                   {product}
   double MinRAMPercentage                          = 50.000000                           {product}

1.默认配置

默认占用容器内存的 1/4 (4G*1/4=1G)

root@eb3a8b28b6d2:/opt/jdk1.8.0_191/bin# ./java -jar /opt/app.jar
  • InitialHeapSize=67108864 (4G*1/64=64MB)
  • MaxHeapSize=1073741824 (1G)
root@eb3a8b28b6d2:/opt/jdk1.8.0_191/bin# ./jinfo -flags 1691
JVM version is 25.191-b12
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=67108864 -XX:MaxHeapSize=1073741824 -XX:MaxNewSize=357564416 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=22020096 -XX:OldSize=45088768 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  

2.设置 MaxRAMFraction

占用容器内存的 100% (4G)

root@eb3a8b28b6d2:/opt/jdk1.8.0_191/bin# ./java -XX:InitialRAMFraction=4 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=1 -jar /opt/app.jar
  • InitialHeapSize=1073741824 (4G*1/4=1G)
  • MaxHeapSize=4294967296 (4G)
  • InitialRAMFraction=4
  • MinRAMFraction=2
  • MaxRAMFraction=1
root@eb3a8b28b6d2:/opt/jdk1.8.0_191/bin# ./jinfo -flags 889
JVM version is 25.191-b12
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=1073741824 -XX:InitialRAMFraction=4 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431306240 -XX:MaxRAMFraction=1 -XX:MinHeapDeltaBytes=524288 -XX:MinRAMFraction=2 -XX:NewSize=357564416 -XX:OldSize=716177408 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -XX:InitialRAMFraction=4 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=1

3.设置 MaxRAMPercentage

占用容器内存的 100% (4G)

root@eb3a8b28b6d2:/opt/jdk1.8.0_191/bin# ./java -XX:InitialRAMPercentage=25.0 -XX:MinRAMPercentage=50.0 -XX:MaxRAMPercentage=100.0 -jar /opt/app.jar

InitialHeapSize=1073741824 (4G*1/4=1G)
MaxHeapSize=4294967296 (4G)
InitialRAMPercentage=25.0
MinRAMPercentage=50.0
MaxRAMPercentage=100.0

root@eb3a8b28b6d2:/opt/jdk1.8.0_191/bin# ./jinfo -flags 977
JVM version is 25.191-b12
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=1073741824 -XX:InitialRAMPercentage=null -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431306240 -XX:MaxRAMPercentage=null -XX:MinHeapDeltaBytes=524288 -XX:MinRAMPercentage=null -XX:NewSize=357564416 -XX:OldSize=716177408 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC 
Command line:  -XX:InitialRAMPercentage=25.0 -XX:MinRAMPercentage=50.0 -XX:MaxRAMPercentage=100.0

总结

  • java版本 >= 8u131,支持 UseCGroupMemoryLimitForHeap,默认关闭,使用 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap 参数来让 JVM 读取容器限制
  • java版本 >= 8u191,支持 UseContainerSupport,默认开启,使用 -XX:+UseContainerSupport 允许JVM 从主机读取 cgroup 限制,例如可用的 CPU 和 RAM,来让 JVM 读取容器限制
  • java版本 >= 8u191,-XX:{Min|Max}RAMFraction 被弃用,引入了-XX:MaxRAMPercentage,其值介于 0.0 到 100.0 之间,默认值为 25.0
  • java版本 >= 10,移除了 InitialRAMFraction、MinRAMFraction、MaxRAMFraction 参数

注意:

  • 如果将这 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap 标志与 Xms 和 Xmx 标志一起设置。-Xmx 标志将覆盖 -XX:+ UseCGroupMemoryLimitForHeap 标志。
  • -Xms 会同时设置 InitialHeapSize 和 MinHeapSize。
  • 如果设置了-Xmx/-Xms,则 InitialRAMPercentage/MaxRAMPercentage/MinRAMPercentage 将无效。
  • 可以设置 MaxDirectMemorySize 指定最大直接内存的大小,如果不显式地设置这个参数,那么直接内存的最大使用量将等同于堆的最大容量。

MaxRAMFraction 默认值是 4

MaxRAMFraction % of RAM for heap
1 100%
2 50%
3 33%
4 25%