首页 > 其他分享 >容器化环境中,JVM最佳参数配置实践

容器化环境中,JVM最佳参数配置实践

时间:2024-02-29 10:38:04浏览次数:18  
标签:容器 Cgroups OpenJDK 1.8 VM XX 参数 内存 JVM

本文分享自华为云社区《Java应用容器化参数配置最佳实践》,作者:可以交个朋友。

简介

当你在物理机或者虚拟机上配置 JVM 参数时,JVM会默认使用主机上1/4的内存作为堆内存,你也可以选择使用-Xmx/-Xms 来指定 Java 堆内存大小。在容器化环境中,每个容器实例的内存大小由Cgroups配置决定,而低版本JVM对Cgroups的支持是不太友好的。本文主要探讨JVM最佳参数配置

JDK与Cgroups的适配关系

JDK 1.8.0_131之前的版本

使用jdk 1.8.0_121版本镜像启动容器实例,不指定参数情况下,无法识别Cgroups内存限制,使用主机1/4的内存作为最大堆内存

[root@172 ~]# free -m
               total        used        free      shared  buff/cache   available
Mem:            7196        2557         299         117        4338        4219
Swap:              0           0           0
[root@172 ~]# docker run -m 512Mi openjdk:8u121 java  -XshowSettings:vm -version VM
VM settings:
    Max. Heap Size (Estimated): 1.56G
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_121"
OpenJDK Runtime Environment (build 1.8.0_121-8u121-b13-1~bpo8+1-b13)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)

使用-Xms-Xmx指定初始堆内存和最大堆内存,jvm能正常识别

[root@172 ~]# docker run -m 512Mi openjdk:8u121 java -Xms512m -Xmx512m -XshowSettings:vm -version VM
VM settings:
    Min. Heap Size: 512.00M
    Max. Heap Size: 512.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_121"
OpenJDK Runtime Environment (build 1.8.0_121-8u121-b13-1~bpo8+1-b13)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)

JDK 1.8.0_131版本

使用jdk 1.8.0_131版本镜像启动容器,不指定参数,无法识别Cgroups内存限制,使用主机1/4的内存作为最大堆内存

[root@172 ~]# docker run -m 512Mi openjdk:8u131 java  -XshowSettings:vm -version VM
VM settings:
    Max. Heap Size (Estimated): 1.56G
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-2-b11)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)

使用-Xms和-Xmx指定初始堆内存和最大堆内存,jvm能正常识别

[root@172 ~]# docker run -m 512Mi openjdk:8u131 java -Xms512m -Xmx512m -XshowSettings:vm -version VM
VM settings:
    Min. Heap Size: 512.00M
    Max. Heap Size: 512.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-2-b11)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)

在jdk 1.8.0_131版本开始,加入了两个新参数-XX:+UnlockExperimentalVMOptions-XX:+UseCGroupMemoryLimitForHeap来动态感知容器的Cgroups内存限制,最大堆内存为Cgroups内存限制的1/4

[root@172 ~]# docker run -m 512Mi openjdk:8u131 java -XX:+UnlockExperimentalVMOptions  -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version VM
VM settings:
    Max. Heap Size (Estimated): 114.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-2-b11)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)

新参数-XX:+UnlockExperimentalVMOptions-XX:+UseCGroupMemoryLimitForHeap虽然能动态感知Cgroups内存限制,但是却只能使用1/4,无法修改。此时可以使用另外两个参数-XX:MaxRAMFraction-XX:MinRAMFraction,参数值必须为整数,取值参考如下表格:

MaxRAMFraction/MinRAMFraction取值Cgroups内存限制的百分比
1 90%
2 50%
3 33%
4 25%
[root@172 ~]# docker run -m 512Mi openjdk:8u131 java -XX:+UnlockExperimentalVMOptions  -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=2 -XshowSettings:vm -version VM
VM settings:
    Max. Heap Size (Estimated): 228.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-8u131-b11-2-b11)
OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)

最大堆内存为Cgroups内存限制的50%,符合预期

JDK 1.8.0_191版本

使用jdk 1.8.0_191版本镜像启动容器,不指定参数,jvm能动态感知Cgroups内存限制,最大堆内存为Cgroups内存限制的1/4

[root@172 ~]# docker run -m 512Mi openjdk:8u191-alpine java  -XshowSettings:vm -version VM
VM settings:
    Max. Heap Size (Estimated): 123.75M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_191"
OpenJDK Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-r0)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

使用-Xms-Xmx指定初始堆内存和最大堆内存,符合预期

[root@172 ~]# docker run -m 512Mi openjdk:8u191-alpine java -Xms512m -Xmx512m -XshowSettings:vm -version VM
VM settings:
    Min. Heap Size: 512.00M
    Max. Heap Size: 512.00M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_191"
OpenJDK Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-r0)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

jdk 1.8.0_191版本开始,-XX:MaxRAMFraction-XX:MinRAMFraction被弃用,使用MaxRAMPercentageMinRAMPercentage来修改堆内存在Cgroups内存限制的占比,参数值是Double类型必须带小数点

[root@172 ~]# docker run -m 512Mi openjdk:8u191-alpine java -XX:MaxRAMPercentage=50.0 -XX:MinRAMPercentage=50.0 -XshowSettings:vm -version VM
VM settings:
    Max. Heap Size (Estimated): 247.50M
    Ergonomics Machine Class: server
    Using VM: OpenJDK 64-Bit Server VM

openjdk version "1.8.0_191"
OpenJDK Runtime Environment (IcedTea 3.10.0) (Alpine 8.191.12-r0)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

总结

  • XmsXmx能适应所有JDK版本,但不能动态感知容器的Cgroups限制,且参数优先级最高,与其他参数一起配置时,其他参数不生效。
  • -XX:+UnlockExperimentalVMOptions-XX:+UseCGroupMemoryLimitForHeap在1.8.0_131版本开始启用,能动态感知容器的Cgroups限制,但最大堆内存只能使用容器Cgroups内存限制的1/4。
  • -XX:MaxRAMFraction-XX:MinRAMFraction在1.8.0_131版本开始启用,可以修改堆内存占容器Cgroups内存限制的百分比,但百分比的值不能自由指定(比如不能指定40%),在1.8.0_191版本开始弃用。
  • MaxRAMPercentageMinRAMPercentage在1.8.0_191版本开始启用,可以自定义修改堆内存占容器Cgroups内存限制的百分比。
以上仅适用于容器采用Cgroups v1版本,在Cgroups v2版本中jdk需要1.8.0_372、11.0.16及更高版本才能动态感知Cgroups的内存限制

JVM参数配置建议

  1. 使用容器感知的 JDK 版本。对于使用 Cgroup V1 的集群,需要升级至 1.8.0_191以及更高版本;对于使用 Cgroup V2 的集群,需要升级至 1.8.0_372、11.0.16及更高版本。
  2. 由于Java应用使用的总内存不仅仅只有堆内存,还有堆外内存和直接内存。所以设置容器内存上限时必须大于堆内存,应该按照 Java 进程使用的内存量上浮 20%~30% 设置容器内存 limit。如果初次运行程序,并不了解其实际内存使用量,可以先设置一个较大的 limit 让程序运行一段时间,根据监控获取实际平均使用值对容器内存 limit 进行调整。
  3. 如果在容器内仅运行一个Java 应用程序,则将初始堆大小与最大堆大小最好配置相等。如果不相等,JVM会根据堆内存使用量在Xms与Xmx之间动态修改堆内存大小,导致额外的系统开销和频繁的垃圾回收。
  4. 使用-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath参数,在JVM发生OOM时,自动生成dump文件。dump文件路径最好是持久化挂载路径避免容器重启dump文件丢失。

点击关注,第一时间了解华为云新鲜技术~

标签:容器,Cgroups,OpenJDK,1.8,VM,XX,参数,内存,JVM
From: https://www.cnblogs.com/huaweiyun/p/18042851

相关文章

  • java参数 -xms -xmx
    参考链接:https://blog.csdn.net/lgleje/article/details/125041480xms、xmx-xms:设置初始化堆内存大小,默认2M-xmx:设置最大可分配堆内存大小,默认64M示例:#初始化128MB堆内存,允许最大堆内存最大1024MB.java-Xms128m-Xmx1024m#初始化256MB堆内存,允许最大......
  • GBJ2510-ASEMI整流桥GBJ2510参数、封装、尺寸
    编辑:llGBJ2510-ASEMI整流桥GBJ2510参数、封装、尺寸型号:GBJ2510品牌:ASEMI封装:GBJ-4最大重复峰值反向电压:1000V最大正向平均整流电流(Vdss):25A功率(Pd):大功率芯片个数:4引脚数量:4类型:插件整流桥、整流桥正向浪涌电流:350A正向电压:1.05V最大输出电压(RMS):封装尺寸:如图工......
  • hbase常见命令和参数
    进入hbaseshell命令行./hbaseshell查看帮助#查看帮助,会列出命令组help#有哪些命令组,常见的CRUD命令在ddl和dml下面COMMANDGROUPS:Groupname:generalGroupname:ddlGroupname:namespaceGroupname:dmlGroupname:tools......
  • 二维数组传参数
    1array<array<int,5>,5>arr;2for(intii=0;ii<arr.size();ii++)3{4for(intjj=0;jj<arr[ii].size();jj++)5{6arr[ii][jj]=jj*10+ii;7}8}9func(arr);1template<typenameT>2voidfunc(c......
  • VS Qt - cmake项目中添加运行时命令行参数
    1、VS在项目目录中找到.vs目录--->launch.vs.json{"version":"0.2.1","defaults":{},"configurations":[{"type":"default","project":"CMakeLists.txt",......
  • FastAPI系列:路径参数额外校验Path
    路径参数额外校验PathfromfastapiimportPathapp=FastAPI()@app.get('/items/{item_id}')asyncdefread_items(item_id:str=Path(default=None,max_length=3,min_length=1,title='theidofitemtoget')):"""def......
  • FastAPI系列:查询字符串参数
    单个查询字符串@app.get('/index/{username}')defindex(username:str,id:int):#id为查询字符串?id=5return{"message":"success","username":username,"id":id}可选的查询字符串参数@app.get('/items/{item_id}......
  • FastAPI系列:全局routes参数的使用
    全局routes参数的使用fromfastapiimportFastAPI,Requestfromfastapi.responseimportJSONResponsefromfastapi.routingimportAPIRouteasyncdeffastapi_index():returnJSONResponse({'index':'fastapi_index'})asyncdeffastapi_about()......
  • FastAPI系列:路由之节点元数据参数说明
    节点元数据参数说明#拿app.get()方法的参数来说明,其他的差不多类似defget(self,path:str,*,response_model:Optional[Type[Any]]=None,status_code:Optional[int]=None,tags:Optional[List[Union[str,Enum]]]......
  • FastAPI系列:路由之APIRouter参数介绍
    APIRouter参数介绍classAPIRouter(routing.Router):def__init__(self,*,prefix:str="",#表示当前路由分组的url前缀tags:Optional[List[Union[str,Enum]]]=None,#表示当前路由分组在可交互文档中所属的分组标签列表。一......