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

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
织梦 CMS “混沌”往事二十年
二十年前,织梦 CMS 是个人站长@IT柏拉图发布的建站软件,通过开源免费的方式,迅速聚集众多用户、贡献者。 而二十年后的今年,卓卓公司以织梦 CMS 版权方的身份大规模起诉用户,要求授权费用,卓卓与织梦 CMS 用户之间纠纷不断…… 这二十年间,织梦 CMS 各个版本的开发由谁主导?织梦 CMS 版权为何到了卓卓公司手中?曾用了 GPL 开源协议的软件是否能向用户收取授权费用?计划报警的织梦 CMS 用户是否能获得想要的结果? 开源中国将长期关注织梦 CMS(DedeCMS)系列版权纠纷案件进展,欢迎知情者私信爆料。 近期开源中国接到多位开发者爆料,称上海卓卓网络科技有限公司(后文简称“卓卓公司”)违反 GPL 协议,试图侵占织梦 CMS 版权,并于 2021 年开始大规模起诉织梦 CMS 用户,给多家公司及相关从业者带来困扰。 在系列诉讼案件中,前期有被告公司疲于应付,赔钱了事。近期卓卓公司对江苏 A 医院的起诉案中,江苏省无锡市中级人民法院在 2024 年 2 月 19 日作出一审判决,认可了 GPL 的 “传染性”,涉案软件(具体版本为 DedeCMSV5.7-sp1)整体按 ...
- 下一篇
关于Python中math 和 decimal 模块的解析与实践
本文分享自华为云社区《Python数学模块深度解析与实战应用》,作者: 柠檬味拥抱。 在Python中,math和decimal模块是处理数学运算的重要工具。math提供了一系列常见的数学函数,而decimal则专注于高精度的浮点数运算。本文将深入探讨这两个模块的基础知识,并通过实际的代码示例演示它们的用法。 1. math模块的基础 1.1 常用数学函数 math模块包含了许多常见的数学函数,比如sin、cos、tan、sqrt等。让我们看一个简单的例子,计算正弦函数的值: import math angle = math.radians(30) # 将角度转换为弧度 sin_value = math.sin(angle) print(f"sin(30°) 的值为:{sin_value}") 在这个例子中,我们使用了radians函数将角度转换为弧度,然后计算了正弦函数的值。 1.2 随机数生成 math模块还提供了生成随机数的函数,比如random。以下是一个简单的随机数生成示例: import math random_number = math.random(...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS8编译安装MySQL8.0.19
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Red5直播服务器,属于Java语言的直播服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7