背景

环境: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. 深度讲解Linux内存管理和Linux进程调度-打通任督二脉

    我在多年的工程生涯中发现很多工程师碰到一个共性的问题:Linux工程师很多,甚至有很多有多年工作经验,但是对一些关键概念的理解非常模糊,比如不理解CPU.内存资源等的真正分布,具体的工作机制,这使得他 ...

  2. redis之PubSub

    前面我们讲了 Redis 消息队列的使用方法,但是没有提到 Redis 消息队列的不足之处,那就是它不支持消息的多播机制. 消息多播 消息多播允许生产者生产一次消息,中间件负责将消息复制到多个消息队列 ...

  3. (三)Kinect姿势识别

    Kinect给我们内置了许多姿势如举手等,具体可参考枚举KinectGestures.Gestures,也可以通过Kinect姿势管理器,自定义姿势导入(坑较多,内置的基本够用了)也可以根据关节坐标自 ...

  4. fenby C语言 P16

    while先判断,不符合,不执行 dowhile后判断,不符合,执行一次 #include <stdio.h> int main(){ int i=1,sum=0; do{ sum=sum ...

  5. 路由器配置深入浅出—路由器接口PPP协议封装及PAP和CHAP验证配置

    知识域: 是针对点对点专线连接的接口的二层封装协议配置 PPP的PAP和CHAP验证,cpt支持,不一定要在gns3上做实验. 路由器出厂默认是hdlc封装,修改为ppp封装后,可以采用pap验证或者 ...

  6. (Java) AES-128 数据加密

    package com.vcgeek.hephaestus.utils; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeyS ...

  7. vue 合成图片

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

  8. Java8系列 (六) 新的日期和时间API

    概述 在Java8之前, 我们一般都是使用 SimpleDateFormat 来解析和格式化日期时间, 但它是线程不安全的. @Test public void test() { SimpleDate ...

  9. 【XSY2985】【BZOJ1367】【Baltic2004】sequence

    考虑两种情况: 1.\(a_1\)<\(a_2\)<\(a_3\)<\(a_4\)...<\(a_n\) 直接令\(b_i\)=\(a_i\),最小. 2.\(a_1\)> ...

  10. GERALD07加强版:lct,主席树,边化点

    Description:N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 传送门. lct这么神仙的东西一个题解都不写怎么行??? 神仙思路啊. 其实不是很难但是的确不容 ...