背景

环境:openshift3.11

开发反映部署在容器中的java应用内存持续增长,只升不降,具体为:

java应用部署在容器中,配置的jvm参数为-Xms1024m -Xmx1024m,容器memory request为1G, memory limit为4G,通过openshift的Pod metrics监控发现,应用消耗内存达到99%(只剩下3M),但是Pod处于Running状态,没有发生OOM,Pod容器java进程正常接收出了请求。增加容器memory limit至8G,内存依然消耗至99%。

排查过程

容器为单进程模型,其中只运行了一个java进程。通过docker stats containerId查看容器消耗的内存为1.735g,通过top命令查看到得java进程的res值为1.7g

查看容器的内存使用信息:

#进入cgroup工作目录
cd /sys/fs/cgroup/memory/ #查找容器id
docker ps | grep {name} #通过容器id查找Pod slice目录,如下
systemd-cgls | grep -C3 contianerId
│ └─kubepods-burstable-pod2df5422b_fed3_11e9_be3c_5254008ade6c.slice
│ ├─docker-b9f2ce762cdc8435167bff21eb2cd31d9e1214ad75f2326bffba5e2f1d46422d.scope #业务容器
│ │ ├─32014 tini -- /run.sh
│ │ └─32584 java -jar /deployments/test.jar
│ └─docker-77fde00b840ba03d4d2d52dd0e08ff2a2db7c85e0233bf2847aaa8fa2250b657.scope #根容器
│ └─28520 /usr/bin/pod #查看内存信息相关目录如下
cat /sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod2df5422b_fed3_11e9_be3c_5254008ade6c.slice/docker-b9f2ce762cdc8435167bff21eb2cd31d9e1214ad75f2326bffba5e2f1d46422d.scope/memory.usage_in_bytes cat /sys/fs/cgroup/memory/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod2df5422b_fed3_11e9_be3c_5254008ade6c.slice/docker-b9f2ce762cdc8435167bff21eb2cd31d9e1214ad75f2326bffba5e2f1d46422d.scope/memory.stat
memory.usage_in_bytes文件中的值即为metrics监控中的值
memory.stat文件中cahce字段的值就是这个容器用于cache的内存

看来metrics监控中的值就是取自memory.usage_in_bytes,而这个值是包含memory.stat中的cache的

那应用为什么会消耗大量cache?

#查看java应用的log4j2配置,发现其中配置了最大保留两个归档文件,每个归档文件大小为2GB,也就是说日志量最大为6GB左右,查看pod中的日志也确实达到了最大的量。做以下步骤验证
1.取消日志输出到文件,metrics监控到得值与dokcer stats或top中的值相近
2.配置最大保留两个归档文件,每个归档文件大小为100M,查看memory.stat中的cache值为350M左右 也就是说log42配置的日志输出到文件会缓存到内存

这个缓存对容器有什么影响吗?

#是没有任何影响的,java进程只消耗内存1.7G左右,剩余的内存是被log4j用于缓存以充分利用内存提高读写效率,当java进程实例消耗内存增加,cache也会相应的释放,这应该是linux的内存机制决定的
Linux has this basic rule: a page of free RAM is wasted RAM. RAM is used for a lot more than just user application data. It also stores data for the kernel itself and, most importantly, can mirror data stored on the disk for super-fast access, this is reported usually as “buffers/cache”, “disk cache” or “cached” by top. Cached memory is essentially free, in that it can be replaced quickly if a running (or newly starting) program needs the memory.

所以在prometheus监控告警中也应该去掉cache这一部分

参考:

http://trustmeiamadeveloper.com/2016/03/18/where-is-my-memory-java/

记一次Pod中java进程内存“异常”消耗的更多相关文章

  1. Android内存管理(11)*常见JVM回收机制「Java进程内存堆分代,JVM分代回收内存,三种垃圾回收器」

    参考: http://www.blogjava.net/rosen/archive/2010/05/21/321575.html 1,Java进程内存堆分代: 典型的JVM根据generation(代 ...

  2. AIX中查看进程内存使用

    AIX中查看进程内存使用 学习了:http://www.2cto.com/os/201308/235858.html 1,从大到小排列10个内存使用率进程 ps aux |  head -1 ;  p ...

  3. Windows中查看进程的资源消耗(cpu, Disk,Memory,NetWork)

    1.通过Windows Task Manager 的 Performance Tab 可以看到总体的性能消耗情况. 2.如果想看系统中每个进程的资源消耗,可以点击 下面的 Open Resource ...

  4. 记一次尴尬的Java应用内存泄露排查

    这星期被线上JVM内存占用不断增大的问题所困扰,自己提出了一些假设,然后去实施验证都一一失败了,有一些经验和教训在这里分享下. 之所以是尴尬,是最后因为修复了另一个看似不相关的问题导致内存不再上升,但 ...

  5. 故障重现, JAVA进程内存不够时突然挂掉模拟

    背景,服务器上的一个JAVA服务进程突然挂掉,查看产生了崩溃日志,如下: # Set larger code cache with -XX:ReservedCodeCacheSize= # This ...

  6. 查看java进程内存简单示例

    分析工具 1.jps 显示指定系统内的所有JVM进程 2.jstat 收集JVM各方面的运行数据 3.jinfo  显示JVM配置信息 4.jmap  堆快照 5.jhat  分析headdump文件 ...

  7. 死磕内存篇 --- JAVA进程和linux内存间的大小关系

    运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...

  8. 深入理解JVM虚拟机11:Java内存异常原理与实践

    本文转自互联网,侵删 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutori ...

  9. Java虚拟机内存区域堆(heap)的管理

    在上一节中Java 出现内存溢出的定位以及解决方案 中对于Java虚拟机栈以及方法区的内存出现的异常以及处理方式进行了解析,由于Java虚拟机对于堆的管理十分复杂,并且Java虚拟机中最基本的内存区域 ...

随机推荐

  1. 百万年薪python之路 -- MySQL数据库之 用户权限

    MySQL用户授权 (来自于https://www.cnblogs.com/dong-/p/9667787.html) 一. 对新用户的增删改 1. 增加用户 : ①. 指定某一个用户使用某一个ip登 ...

  2. IDEA配置maven+错误记录

    使用maven并不是那么顺利所以把自己遇到的问题也记录一下 下载maven 从官网下载maven官网 配置环境变量 新建一个变量名:MAVEN_HOME 值:maven目录 path:%MAVEN_H ...

  3. LeetCode刷题笔记(1)常用知识点

    1.Integer.parseInt(String s, int radix)方法的作用是:将radix进制的字符串s转化成10进制的int型数字并返回. Integer.valueof(String ...

  4. unity 序列帧播放

    [SerializeField] private Image m_ScreenImage; //序列帧播放的image [SerializeField] ; // 一秒播放的帧数 [Serialize ...

  5. 随机数产生器:Random.Next

    Random类是一个产生伪随机数字的类,它的构造函数有两种,一个是直接New Random(),另外一个是New Random(Int32),前者是根据触发那刻的系统时间做为种子,来产生一个随机数字, ...

  6. GUI编程(Tkinter) 笔记分享

    Python GUI编程(Tkinter) Python 提供了多个图形开发界面的库,几个常用 Python GUI 库如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的 ...

  7. vue 合成图片

    目的:将二维码图片和背景图片合成变成一张图片 方法一: 引入依赖 cnpm install qrcanvas --save cnpm install html2canvas --save 具体代码: ...

  8. 重磅!微软发布 Visual Studio Online:Web 版 VS Code + 云开发环境

    北京时间 2019 年 11 月 4 日,在 Microsoft Ignite 2019 大会上,微软正式发布了 Visual Studio Online (VS Online)公开预览版! 如今发布 ...

  9. ubuntu中nfs安装

    Ubuntu Nfs服务器安装 nfs服务器在嵌入式开发中非常常用,可以实现主机和开发板共享文件.    1.安装软件包    sudo apt-get install nfs-common nfs- ...

  10. vue cli3.0^版本处理文件下载的问题

    downloadFile(url, fileName) { axios.get(url, { responseType: 'blob' }) .then(({ data }) => { // 为 ...