JVM 在容器环境的内存配置

如果容器资源没有设置任何 limits 并且Java没有设置额外参数的话,Java应用会默认使用宿主机 1/4 的内存作为 MaxHeapSize ,可通过如下命令验证:

$ docker run --rm -ti 129.0.4.40/common/jdk:8 java -XX:+PrintFlagsFinal -version | grep MaxHeapSize                                                                               uintx MaxHeapSize                              := 4164943872 

测试宿主机是16G内存,4164943872/1024/1024 ~ 4G

首先查看使用JDK版本是否支持 UseContainerSupport 参数,如果支持该参数,则JVM会自动读取容器限制的内存值,读取文件:/sys/fs/cgroup/memory/memory.limit_in_bytes

该参数在 Java 8u191+,10以及更高的版本中支持

$ docker run --rm -ti 129.0.4.40/common/jdk:8 java -XX:+PrintFlagsFinal -version | grep UseContainerSupport bool UseContainerSupport = true {product}

返回true则表示支持,没有任何返回表示不支持

 

 

支持 UseContainerSupport


实验使用的Java版本是

java version "1.8.0_202"Java(TM) SE Runtime Environment (build 1.8.0_202-b08)Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)使用 -XX:MaxRAMPercentage 参数来配置JVM可用容器限制的资源百分比,默认是25.0 取值范围是 0.0 到 100.0

$ docker run --rm -ti -m 2000m 129.0.4.40/common/jdk:8 java -XX:+PrintFlagsFinal -version | grep MaxHeapSize    uintx MaxHeapSize                              := 524288000    $ docker run --rm -ti -m 2000m 129.0.4.40/common/jdk:8 java -XX:MaxRAMPercentage=80.0 -XX:+PrintFlagsFinal -version | grep MaxHeapSize    uintx MaxHeapSize                              := 1677721600 

如上示例显示,如果容器限制了2000m的内存,默认JVM使用 1/4 的量,即500m

如果配置了 -XX:MaxRAMPercentage 参数,这里设置为80.0,表示JVM使用限制内存的80%,即1600m

建议值为75.0

 

 

不支持 UseContainerSupport


实验使用的Java版本是

java version "1.8.0_152"Java(TM) SE Runtime Environment (build 1.8.0_152-b16)Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)

使用 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap 参数来让JVM读取容器限制

不过默认即使加上这两个参数,JVM也只会使用容器限制内存的 1/4 的量,可以再添加一个参数 -XX:MaxRAMFraction ,该参数表示使用可用内存的基数,默认是4

JVM可用最大heap内存=最大可用内存*1/MaxRAMFraction

$ docker run --rm -ti -m4000m 129.0.4.40/common/jdk:8.1 java -XX:+PrintFlagsFinal -version | grep MaxHeapSizeuintx MaxHeapSize                              := 4164943872
$ docker run --rm -ti -m4000m 129.0.4.40/common/jdk:8.1 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:+PrintFlagsFinal -version | grep MaxHeapSizeuintx MaxHeapSize                              := 1048576000                          
$ docker run --rm -ti -m4000m 129.0.4.40/common/jdk:8.1 java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2 -XX:+PrintFlagsFinal -version | grep MaxHeapSizeuintx MaxHeapSize                              := 2097152000

如上示例显示,如果容器限制了4000m的内存,默认JVM使用宿主机 1/4 的内存,即4G

如果配置了 -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap 参数,则JVM使用容器限制内存的 1/4,即4000m*1/4=1000m

如果配置了 -XX:MaxRAMFraction=2 ,则JVM使用容器限制内存的 1/2,即 4000m*1/2=2000m

设置 MaxRAMFraction 为1表示将容器所有内存分配给JVM,不建议这么做,需要给其他程序预留部分内存

Java 10 移除了 -XX:{Initial|Min|Max}RAMFraction 参数

对于 Java SE 8u121 以及之前的版本这些参数都不生效,只能通过 -Xms1000m -Xmx2000m 这种方式进行限制

-Xmx 参数即使设置了2000m,JVM也会分配比2000m多的内存,如果想将JVM完全限制在2000m以内,需要使用 -XX:MaxRAM 参数

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值