背景

客户使用我们的产品,我们产品默认监控内存使用的container_memory_working_set_bytes相关,后来一个同事的建议下,客户改为container_memory_rss相关,最近接手这个项目,客户问我这俩有啥区别。

简介

  1. container_memory_rss
  • 指标名称:container_memory_rss
  • 指标类型:Gauge(表示某一时刻的数值)
  • 解析逻辑:该指标使用了Linux的/proc文件系统,读取了容器进程的/proc/[PID]/statm文件,其中PID是容器进程的进程ID。在该文件中,第2列表示进程的Resident Set Size (RSS),即实际驻留在物理内存中的大小。Prometheus的采集器会定期读取这个值,并将其暴露为container_memory_rss指标。
  1. container_memory_working_set_bytes
  • 指标名称:container_memory_working_set_bytes
  • 指标类型:Gauge
  • 解析逻辑:类似于container_memory_rss,该指标也使用了Linux的/proc文件系统,读取了容器进程的/proc/[PID]/statm文件。在该文件中,第6列表示进程的Working Set Size,即进程当前使用的物理内存大小。Prometheus的采集器会定期读取这个值,并将其暴露为container_memory_working_set_bytes指标。

man手册

/proc/[pid]/statm

  1. size:表示进程的虚拟内存空间大小(以页面为单位)。它包括进程代码段、数据段、堆、栈和共享库等。
  2. resident:表示进程当前驻留在物理内存中的页面数量(以页面为单位)。它指示进程当前实际使用的物理内存量。
  3. shared:表示进程使用的共享内存的页面数量(以页面为单位)。共享内存是多个进程之间共享的内存区域。
  4. data:表示进程数据段的页面数量(以页面为单位)。数据段包含了进程的全局变量、静态变量和堆分配的动态数据等。

注:单位页:OS默认一页4KB。

/proc/[pid]/status

(内容太多,截取了相关部分)

从简介和man手册中我们可以得出

container_memory_rss == VmRSS

container_memory_working_set_bytes == data

linux内存说明

理解VIRT、RES、data

让我们先抛开上面的内容,来了解下linux中的内存,那么上面的东西也就呼之欲出了。

我们来看下面的命令和几个名词

[root@cubblestone ~]# ps -aux | egrep "USER|3769" | grep -v grep
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      3769  1.1  3.1 1065188 64960 ?       Sl   May15 324:56 /usr/local/qcloud/YunJing/YDEyes/YDService
[root@cubblestone ~]# top -b -n1 | egrep "USER|3769"
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 3769 root      20   0 1065188  65756  13556 S   0.0  3.2 324:57.70 YDService
[root@cubblestone ~]# cat /proc/3769/statm 
266297 16439 3389 6073 0 251356 0

VIRT(Virtual Memory Size,虚拟内存大小):VIRT表示进程可寻址的虚拟内存的总量,包括实际内存和虚拟内存(如共享库、映射文件等)。VIRT的值可能会比实际系统可用内存大,因为它包括了虚拟内存的总和。

VSZ VIRT的旧称,实际是一个概念。

RES(Resident Set Size,常驻集合大小):RES表示进程当前使用的实际物理内存的大小。它只计算进程实际占用的物理内存部分,不包括虚拟内存的部分。

RSS RES的旧称,实际是一个概念。

data 字段表示进程数据段的页面数量,即进程已分配的数据段的大小。数据段包含了进程的全局变量、静态变量和堆分配的动态数据等。可以理解为数据段已申请的内存大小。

举例:当程序向OS申请100M内存,但实际只使用了10M时,那么VIRT增加了100M,RES增加了10M,而data的增长位于10M~100M之间。

小结:VIRT代表总的已申请的虚拟内存,包括数据段,共享库等。data表示数据段已申请的总内存。而RES表示实际占用物理的内存。所以,VIRT包含data,data包含RES。

所以真实的内存我们参考RES而不是VIRT和data,也就是container_memory_rss。

总结

监控的时候,如果想了解进程使用的实际内存,请参考container_memory_rss,即RES。

container_memory_rss == VmRSS == RSS = RES
container_memory_working_set_bytes == data

蓝色瞳仁
33 声望2 粉丝

IT咸鱼,愿不忘初心