当前位置: 首页 > article >正文

Openjdk 8合理使用容器的内存资源

前言

将Java应用容器化虽然更好地解决了可移植性问题,但也存在着一些不友好的情况,比如低版本的JDK(低于Java 8u131)并不能识别 CGroup资源限制。这将导致JVM读取的是宿主机的全部CPU和内存,一但容器使用资源超过限制则会被docker杀死。

在 kubernetes 中,我们会显示在 yaml 文件中配置CPU、内存请求和限制,我们希望容器中的JVM进程能够自动识别到 CGroup 资源限制,获取到正确的内存和CPU信息从而自行动态调整。

JVM 参数配置

以下操作皆在一台 4C 16G 服务器上进行。

01 版本低于 8u131

JDK 版本低于 8u131 版本的 JVM 不会自动识别到 CGroup 资源限制,需要手动设置初始堆大小以及最大堆大小,否则会按照宿主机的全部内存设置默认值:

-配置最大堆大小 -Xmx,默认值:内存的1/4

-配置初始堆大小 -Xms,默认值:内存的1/64

未配置JVM参数

可以看到 Max. Heap Size (Estimated): 3.48G,未能正确识别 CGroup 资源限制

$ docker run --rm -m 2GB openjdk:8u121-alpine java -XshowSettings:vm -versionVM settings:Max. Heap Size (Estimated): 3.48GErgonomics Machine Class: serverUsing VM: OpenJDK 64-Bit Server VMopenjdk version "1.8.0_121"OpenJDK Runtime Environment (IcedTea 3.3.0) (Alpine 8.121.13-r0)OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)
配置JVM参数

配置 -Xmx 和 -Xms 后即可达到我们想要的结果

$ docker run --rm -m 2GB openjdk:8u121-alpine java -XshowSettings:vm -Xmx2000m -Xms2000m -versionVM settings:Min. Heap Size: 1.95GMax. Heap Size: 1.95GErgonomics Machine Class: serverUsing VM: OpenJDK 64-Bit Server VMopenjdk version "1.8.0_121"OpenJDK Runtime Environment (IcedTea 3.3.0) (Alpine 8.121.13-r0)OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)
02 8u131 及以上版本

从 8u131 版本开始支持 UseCGroupMemoryLimit

ForHeap 和 MaxRAMFraction 这两个选项,用 CGroupMemory 的大小作为 JVM heap size,MAXRAMFraction 是用来控制实际可用的内存数量的,比如设置为 1 的话就是 CGroupMemoryLimit 的全部,设置为 2 的话一半,3 的话就是 1/3,以此类推

未配置JVM参数

可以看到 Max. Heap Size (Estimated): 3.48G,未能正确识别 CGroup 资源限制

$ docker run --rm -m 2GB openjdk:8u131-alpine java -XshowSettings:vm -versionVM settings:Max. Heap Size (Estimated): 3.48GErgonomics Machine Class: serverUsing VM: OpenJDK 64-Bit Server VMopenjdk version "1.8.0_131"OpenJDK Runtime Environment (IcedTea 3.4.0) (Alpine 8.131.11-r2)OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)
配置JVM参数

配置

-XX:+UnlockExperimentalVMOptions、

-XX:+UseCGroupMemoryLimitForHeap 和

-XX:MaxRAMFraction=1 后即可达到我们想要的结果

$ docker run --rm -m 2GB openjdk:8u131-alpine java -XshowSettings:vm -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1 -versionVM settings:Max. Heap Size (Estimated): 1.78GErgonomics Machine Class: serverUsing VM: OpenJDK 64-Bit Server VM openjdk version "1.8.0_131"OpenJDK Runtime Environment (IcedTea 3.4.0) (Alpine 8.131.11-r2)OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode)
03 8u191 及以上版本

从 8u191 开始引入了 java10+ 上的 UseContainerSupport 选项,而且是默认启用的,不用设置。同时 UseCGroupMemoryLimitForHeap 这个就弃用了,不建议继续使用,同时还可以通过 -XX:InitialRAMPercentage、-XX:MaxRAMPercentage、-XX:MinRAMPercentage 这些参数更加细腻的控制 JVM 使用的内存比率。比如一些 Java 程序在运行时会调用外部进程、申请 Native Memory 等,所以即使是在容器中运行 Java 程序,也得预留一些内存给系统的。所以 -XX:MaxRAMPercentage 不能配置得太大。

未配置JVM参数

可以看到未添加任何 JVM 参数即可正确识别到 CGroup 资源限制

$ docker run --rm -m 2GB openjdk:8u191-alpine java -XshowSettings:vm -versionVM settings:Max. Heap Size (Estimated): 455.50MErgonomics Machine Class: serverUsing VM: OpenJDK 64-Bit Server VMopenjdk 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)
配置JVM参数

使用 -XX:MaxRAMFraction 参数调整 Max. Heap Size 大小

$ docker run --rm -m 2GB openjdk:8u191-alpine java -XX:MaxRAMFraction=1 -XshowSettings:vm -versionVM settings:Max. Heap Size (Estimated): 1.78GErgonomics Machine Class: serverUsing VM: OpenJDK 64-Bit Server VMopenjdk 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)

使用 -XX:InitialRAMPercentage、-XX:MaxRAMPercentage、-XX:MinRAMPercentage 参数更加细腻的控制 JVM 使用的内存比率

$ docker run --rm -m 2GB openjdk:8u191-alpine java -XX:InitialRAMPercentage=40.0 -XX:MaxRAMPercentage=90.0 -XX:MinRAMPercentage=50.0 -XshowSettings:vm -versionVM settings:Max. Heap Size (Estimated): 1.60GErgonomics Machine Class: serverUsing VM: OpenJDK 64-Bit Server VMopenjdk 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)

参考资料

  • http://www.51gjie.com/java/551.html

  • https://zhuanlan.zhihu.com/p/140849800

  • https://my.oschina.net/neverforget/blog/4779579

  • https://sevenyu.top/2019/04/01/java-resources-limit.html

  • https://qingmu.io/2018/12/17/How-to-securely-limit-JVM-resources-in-a-container/

http://www.lryc.cn/news/2420740.html

相关文章:

  • 每天一个linux命令(54):ping命令
  • [随笔所想] 沉痛悼念开发技术专家毛星云老师
  • 罗马音平假字复制_LISA-- 炎(罗马音+平假)
  • 智能客服项目实战
  • 【让这些电影给你“治病”】
  • 过滤及提取电影资源名小算法(初级方案)
  • 淘宝抢拍器 chrome extension实现
  • 数据库安全性最佳实践:防护数据泄露和攻击的方法
  • 移动端设置固定比例的盒子,让图片铺满盒子,并设置默认图片
  • 使用ApexSQLLog对SQL Server数据库进行数据恢复
  • NouveauParfum
  • 友思特新品 | 多光谱与高光谱相机:基于随心而定的可调谐滤光片技术
  • 外贸独立站可获取流量的渠道有哪些?外贸网站引流真的那么难吗?- 【飞鱼SEO】
  • MATLAB作图方法与技巧
  • python图像模糊处理_Python图像处理,照片去色、翻转、模糊、缩略图统统搞定
  • 神之浩劫2登不上/连不上/进不去游戏/游戏进不去的解决办法
  • Zookeeper--集群及相关概念
  • 博客 Gif 动态图制作 - 插入gif动态图 GifCam
  • 地图之美(地图制图)
  • 2024年第二十一届 五一杯 (A题)大学生数学建模挑战赛 | 多目标优化问题,深度学习分析 | 数学建模完整代码解析
  • 高数15种常见特殊曲线:星形线、心形线、摆线、对数螺线、双曲螺线、阿基米德螺线、伯努利双纽线、三叶玫瑰线、四叶玫瑰线、六叶玫瑰线、三次抛物线、半立方抛物线、箕舌线、蔓叶线、笛卡儿叶形线、概率曲线
  • 06 Oracle数据是怎么存储的
  • 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 ‘Users‘ 中的标识列插入显式值
  • python之爬虫爬取VIP蔬菜网农产品价格行情(使用requests库 + HTML)
  • 01、java、jdk、jre三者之间的区别与联系(包含java环境 配置)
  • APM —全链路追踪
  • 混合密集网络(Mixture Density Networks)
  • 『现学现忘』Git后悔药 — 34、git commit --amend 命令
  • 安卓开发:安卓应用上架主流平台汇总
  • Linux bind函数详解