每日一博 | 云原生背景下如何配置 JVM 内存
背景
前段时间业务研发反馈说是他的应用内存使用率很高,导致频繁的重启,让我排查下是怎么回事;
在这之前我也没怎么在意过这个问题,正好这次排查分析的过程做一个记录。
首先我查看了监控面板里的 Pod 监控:
发现确实是快满了,而此时去查看应用的 JVM 占用情况却只有30%左右;说明并不是应用内存满了导致 JVM 的 OOM,而是 Pod 的内存满了,导致 Pod 的内存溢出,从而被 k8s 杀掉了。
而 k8s
为了维持应用的副本数量就得重启一个 Pod,所以看起来就是应用运行一段时间后就被重启。
而这个应用配置的是 JVM 8G,容器申请的内存是16G,所以 Pod 的内存占用看起来也就 50% 左右。
容器的原理
在解决这个问题之前还是先简单了解下容器的运行原理,因为在 k8s 中所有的应用都是运行在容器中的,而容器本质上也是运行在宿主机上的一个个经常而已。
但我们使用 Docker 的时候会感觉每个容器启动的应用之间互不干扰,从文件系统、网络、CPU、内存这些都能完全隔离开来,就像两个运行在不同的服务器中的应用。
其实这一点也不是啥黑科技,Linux 早就支持 2.6.x 的版本就已经支持 namespace
隔离了,使用 namespace
可以将两个进程完全隔离。
仅仅将资源隔离还不够,还需要限制对资源的使用,比如 CPU、内存、磁盘、带宽这些也得做限制;这点也可以使用 cgroups
进行配置。
它可以限制某个进程的资源,比如宿主机是 4 核 CPU,8G 内存,为了保护其他容器,必须给这个容器配置使用上限:1核 CPU,2G内存。
这张图就很清晰的表示了 namespace
和 cgroups
在容器技术中的作用,简单来说就是:
- namespace 负责隔离
- cgroups 负责限制
在 k8s 中也有对应的提现:
resources: requests: memory: 1024Mi cpu: 0.1 limits: memory: 1024Mi cpu: 4
这个资源清单表示该应用至少需要为一个容器分配一个 0.1 核和 1024M 的资源,CPU 的最高上限为 4 个核心。
不同的OOM
回到本次的问题,可以确认是容器发生了 OOM 从而导致被 k8s 重启,这也是我们配置 limits 的作用。
k8s 内存溢出导致容器退出会出现 exit code 137 的一个 event 日志。
因为该应用的 JVM 内存配置和容器的配置大小是一样的,都是8GB,但 Java 应用还有一些非 JVM 管理的内存,比如堆外内存之类的,这样很容易就导致容器内存大小超过了限制的 8G 了,也就导致了容器内存溢出。
云原生背景的优化
因为这个应用本身使用的内存不多,所以建议将堆内存限制到 4GB,这样就避免了容器内存超限,从而解决了问题。
当然之后我们也会在应用配置栏里加上建议:推荐 JVM 的配置小于容器限制的 2/3,预留一些内存。
其实本质上还是开发模式没有转变过来,以传统的 Java 应用开发模式甚至都不会去了解容器的内存大小,因为以前大家的应用都是部署在一个内存较大的虚拟机上,所以感知不到容器内存的限制。
从而误以为将两者画了等号,这一点可能在 Java 应用中尤为明显,毕竟多了一个 JVM;甚至在老版本的 JDK 中如果没有设置堆内存大小,无法感知到容器的内存限制,从而自动生成的 Xmx 大于了容器的内存大小,以致于 OOM。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
System76 COSMIC 桌面环境完善“面板”功能,支持自定义
COSMIC 是老牌 Linux PC 厂商 System76 专为 Pop!_OS 发行版打造的桌面环境,采用 Rust 编写,并使用了原生 Rust 跨平台图形工具包 Iced。 Iced 是一个为 Rust 编程语言编写的跨平台 GUI 库,“专注于简单性和类型安全”。Iced 的设计思路受到了 Elm 语言的启发。Iced 工具包不仅适用于 Linux、macOS 和 Windows,还适用于 Web 应用程序。 COSMIC 并不是从头开始构建的产品,而是基于 GNOME 桌面环境打造,System76 希望以此为基础在 Pop!_OS 中提供完善的、经过精心打磨的桌面用户体验。两者最大的区别,同时也是 COSMIC 最大的亮点就是可定制化。System76 认为这是一个优雅的解决方案,它设想通过定制化的方式让桌面更易于使用,对用户而言,这是一项强大且高效的特性。 System76 上周介绍了COSMIC 最新的开发进展,主要是“面板” (COSMIC Panels) 功能。 “面板”类似于 Pop!_OS 中的顶部栏和停靠栏,但功能更丰富,位置调整也更灵活。它包含许多...
- 下一篇
AnyLabeling —— AI 自动标注工具
AnyLabeling 是一款自动标注工具,可以使用YOLOv5,YOLOv8,Segment Anything,或者自定义模型进行标注。 多边形、矩形、圆形、直线和点的图像注释。 使用 YOLOv5YOLOv8和Segment Anything自动标注。 文本检测、识别和 KIE(关键信息提取)标签。 提供多种语言:英语、越南语、中文。 安装命令 conda create -n anylabeling python=3.8 conda activate anylabeling pip install anylabeling # pip install anylabeling-gpu # 如果CUDA环境搭建好,可以选择GPU版 使用命令 anylabeling
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- Linux系统CentOS6、CentOS7手动修改IP地址
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Docker快速安装Oracle11G,搭建oracle11g学习环境