Linux进程、Cgroup、容器的内存指标

在 Linux 上监控内存开销时,存在多种指标,本文区分它们的定义、用途。

进程内存

  • Linux 会准确记录每个进程占用的 CPU 时长,但统计一个进程占用的内存比较麻烦、有误差,常见的算法有 RSS、WSS 等。

    • 内核会记录每个内存 Page 是否被进程占用,但不知道被哪个进程占用。
  • 虚拟集(Virtual Set Size,VSZ)

    • :进程申请分配的内存量。
    • 例如进程多次调用 malloc() ,申请分配多块内存空间。它们的体积之和就是 VSZ 。
  • 常驻集(Resident Set Size ,RSS)

    • :进程长期驻留的内存量。是指进程的 Page Table 中,引发过缺页异常的 Pages 数。
    • 假设进程 A 申请分配了 10MB 内存空间,实际只在 2MB 内存空间中写入了数据。则 VSZ 为 10MB , RSS 为 2MB 。
      • 如果进程释放一些已用内存,则统计的 RSS 不会减少。因此 RSS 可能比进程实际占用的内存虚高。
    • RSS = 进程占用的非共享内存 + SHR。
      • RSS 包括堆、栈、共享内存,不包括 Swap ,也不包括 page tables、huge page、kernel stack、struct thread_info、struct task_struct 等。
      • 用如下命令可统计所有进程的 RSS 内存之和,但这样会重复累计 SHR 内存,因此计算结果比所有进程实际占用的内存量虚高。为了减少误差,应该统计所有进程的 PSS 内存之和。
        ps -eo rss | awk 'NR>1' | awk '{sum+=$1} END {print sum/1024}'
        
  • SHR

    • :Shared Memory ,进程占用的共享内存。
    • 例如多个进程可能导入同一个共享库 glibc 。
  • 比例集(Proportional Set Size,PSS)

    • :按比例估算出进程的常驻内存。
    • PSS = 进程独占的非共享内存 + 进程平均占用的 SHR
    • 假设进程 A 的 RSS 为 10MB ,其中 8MB 为非共享内存,2MB 为与其它 N 个进程共享的内存。则进程 A 的 PSS = 8 + 2/(N+1) MB 。
  • 工作集(Working Set Size ,WSS)

    • :进程保持工作所需的内存。是估算进程最近访问过的 Pages 数,包括物理内存、内核内存、脏页。
    • 一个进程的 RSS 总是大于等于 WSS ,因为 RSS 可能虚高。

Cgroup内存

  • Linux Cgroup 用于分组管理进程。一个 Cgroup 内可以包含一组多个进程,通过 Cgroup 参数监控、限制它们的CPU、内存开销。
    • 例如用 cat /sys/fs/cgroup/memory/memory.stat 可查看 Cgroup 的内存指标。
    • 关于内存的几个 Cgroup 参数:
      memory.limit_in_bytes # 限制进程最大的内存使用量,取值为 -1 则不限制
      memory.usage_in_bytes # 记录进程当前的内存使用量,包括 RSS、swap、Page Cache
      memory.oom_control    # 取值为 0 时,启用 OOM-killer ,当进程占用的内存超过限制时杀死它。取值为 1 时,禁用 OOM-killer ,只会暂停进程
      

容器内存

  • Docker 基于 Linux Cgroup 技术限制容器占用的 CPU、内存等系统资源,每个容器属于一个 Cgroup 。
  • 通常使用 cAdvisor 监控容器,它会读取容器的 Cgroup 参数,生成以下监控指标:
    container_memory_usage_bytes              # 容器占用的全部内存,读取自 Cgroup 的 memory.usage_in_bytes 文件,等于 rss + swap + cache
    container_memory_rss                      # 容器占用的 rss 内存,读取自 Cgroup 的 memory.stat 文件中的 total_rss 字段
    container_memory_swap                     # 容器占用的 swap 内存
    container_memory_cache                    # 容器占用的 Page Cache 内存
    container_memory_working_set_bytes        # 容器的工作集内存,等于 memory.usage_in_bytes - memory.stat.total_inactive_file
    
    • 假设容器启动之后不断增加内存,则当 container_memory_usage_bytes 达到 Cgroup 限制的 memory.limit_in_bytes 时,不会触发 OOM ,而是停止增长。
      • 因为 container_memory_usage_bytes = rss + swap + cache ,在总和 container_memory_usage_bytes 不变的情况下,容器可以减少 container_memory_cache ,继续增加 container_memory_rss 。
      • 当 container_memory_working_set_bytes 达到 Cgroup 内存限制时,会触发 OOM ,杀死容器内进程。
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值