背景
客户使用我们的产品,我们产品默认监控内存使用的container_memory_working_set_bytes相关,后来一个同事的建议下,客户改为container_memory_rss相关,最近接手这个项目,客户问我这俩有啥区别。
简介
- container_memory_rss:
- 指标名称:container_memory_rss
- 指标类型:Gauge(表示某一时刻的数值)
- 解析逻辑:该指标使用了Linux的/proc文件系统,读取了容器进程的/proc/[PID]/statm文件,其中PID是容器进程的进程ID。在该文件中,第2列表示进程的Resident Set Size (RSS),即实际驻留在物理内存中的大小。Prometheus的采集器会定期读取这个值,并将其暴露为container_memory_rss指标。
- 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
- size:表示进程的虚拟内存空间大小(以页面为单位)。它包括进程代码段、数据段、堆、栈和共享库等。
- resident:表示进程当前驻留在物理内存中的页面数量(以页面为单位)。它指示进程当前实际使用的物理内存量。
- shared:表示进程使用的共享内存的页面数量(以页面为单位)。共享内存是多个进程之间共享的内存区域。
- 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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。