引 言: top命令作为Linux下最常用的性能分析工具之一,可以监控、收集进程的CPU、IO、内存使用情况。比如我们可以通过top命令获得一个进程使用了多少虚拟内存(VIRT)、物理内存(RES)、共享内存(SHR)。

最近遇到一个咨询问题,某产品做性能分析需要获取进程占用物理内存的实际大小(不包括和其他进程共享的部分),看似很简单的问题,但经过研究分析后,发现背后有很多故事……

1 VIRT RES SHR的准确含义

三个内存指标,VRIT,RES,SHR准确含义是什么?谁能告诉我们?MAN页?Linux专家?SUSE工程师?Linus?谁能说出最正确答案?没人!因为惟有源代码才是最正确的答案。

那我们就去看下源码吧,这就是开源软件的最大的好处。

首先这三个数据的源头,肯定是内核,进程的相关数据结构肯定是由内核维护。那么top作为一个用户空间的程序,要想获取内核空间的数据,就需要通过系统接口(API)获取。而proc文件系统是Linux内核空间和用户空间交换数据的一个途径,而且是非常重要的一种途径,这点和windows更倾向于基于函数调用的形式不同。

当你调用系统函数read读取一个普通文件时,内核执行对应文件系统的代码从磁盘传送文件内容给你。

当你调用系统函数read读取一个 proc文件时,内核执行对应的proc文件系统的代码从内核的数据结构中传送相关内容给你。proc文件和磁盘没有关系。只是系统接口而已。

而一个进程的相关信息,Linux全部通过/proc/<pid>/内的文件告诉了我们。

如下,你可以使用普通的文件读写工具,比如cat获取进程的各种信息。这比函数调用的方式灵活多了、丰富多了。

回到我们的问题,top命令显示的进程信息,肯定也是通过proc获取的,因为除此之外没有其他途径,没有系统函数可以做这个事情,top也不可能越过用户层直取内核获取数据。

带着以上信息,很快就可以从top的源码中找到关键代码:

啊哈,statm文件:

根据sscanf的顺序,第一个值是VIRT,第二个值是RES,第三个值是SHR!

等等,好像数值对不上,top显示的SHR是344k,而statm给出的是86!

再来看一行关键代码:

statm显示的是页数,top显示的是KB。X86下,一页是4KB,86 * 4 = 344。这就对了!

于是乎,我们找到了最关键的入口,接下来按图索骥,看看内核是怎么产生statm文件内容就可以了。~~

proc_pid_statm函数负责产生statm文件内容,当你使用cat命令打印statm文件时,内核中的这个函数会执行。

proc_pid_statm获取进程的mm_struct数据结构,而这个数据结构就是进程的内存描述符,通过它可以获取进程内存使用、映射的全部信息。

进一步考察task_statm函数,可以看到:

第一个值(VIRT)就是mm->total_vm,即进程虚存的总大小,这个比较清晰,只要进程申请了内存,无论是malloc还是堆栈还是全局,都会计入这个值;

第二个值(RES)是mm->file_rss+mm->anon_rss;

第三个值(SHR)是mm->file_rss。

RES要和SHR结合者看,内核把物理内存分为了两部分,一部分是映射至文件的,一部分是没有映射至文件的即匿名内存,完全和共不共享没有关系!

但file_rss为什么叫做shared呢?应该是一种指示性表述,表示这部分内存可能是共享的。但并不代表真正共享了。那么到底哪些计入file_rss?通过查阅相关代码,发现(可能有遗漏):

l 程序的代码段。

l 动态库的代码段。

l 通过mmap做的文件映射。

l 通过mmap做的匿名映射,但指明了MAP_SHARED属性。

l 通过shmget申请的共享内存。

即进程通过以上方式占用的物理内存,计入file_rss,也就是top的SHR字段。我们看到一般这些内存都是以共享方式存在。但如果某个动态库只一个进程在使用,它的代码段就没有被共享着。

反过来再来看anon_rss统计的内容,是否就一定是独占的?也不是,比如新fork之后的子进程,由于copy on write机制,在页面被修改之前,和父进程共享。这部分值并不体现在top命令的SHR字段内。

综上所述top命令显示的SHR字段,并不是准确描述了进程与其他进程共享使用的内存数量,是存在误差的。

那么如何获取进程准确的共享内存数量?

2 获取进程准确的共享内存数量

我们注意到在描述进程信息的proc/<pid>内,有一个smaps文件,里面展示了所有内存段的信息,其中有Shared_Clean Shared_Dirty Private_Clean Private_Dirty:几个字段。

找到相关代码,可以看到,一个页面如果映射数>=2计入Shared_* ; 如果=1计入Private_*。(脏页计入*_Dirty,否则计入*_Clean)

统计smaps文件内所有段的Shared_*值的总和就是进程准确的共享内存数量!

统计smaps文件内所有段的Private_*值的总和就是进程准确的独占内存数量!

3 总结

通过以上分析,我们可以得到如下结论:

l top命令通过解析/proc/<pid>/statm统计VIRT和RES和SHR字段值。

l VIRT是申请的虚拟内存总量。

l RES是进程使用的物理内存总和。

l SHR是RES中”映射至文件”的物理内存总和。包括:

程序的代码段。

动态库的代码段。

通过mmap做的文件映射。

通过mmap做的匿名映射,但指明了MAP_SHARED属性。

通过shmget申请的共享内存。

l /proc/<pid>/smaps内Shared_*统计的是RES中映射数量>=2的物理内存。

l /proc/<pid>/smaps内Private_*统计的是RES中映射数量=1的物理内存。

转 linux进程内存到底怎么看 剖析top命令显示的VIRT RES SHR值相关推荐

  1. 剖析top命令显示的VIRT RES SHR值

    http://yalung929.blog.163.com/blog/static/203898225201212981731971/ http://www.fuzhijie.me/?p=741 引 ...

  2. Linux下的top命令PR,NI,VIRT,RES,SHR,S的解释

    今天在观察服务器运行情况的时候用top命令看我的程序是否在运行,一般只关心内存,CPU这些参数,但是它还有很多的参数,我们一起来看看其他的参数都是什么意思. VIRT:Virtual memory u ...

  3. Linux Used内存到底哪里去了?

    原创文章,转载请注明: 转载自系统技术非业余研究 本文链接地址: Linux Used内存到底哪里去了? 前几天 纯上 同学问了一个问题: 我ps aux看到的RSS内存只有不到30M,但是free看 ...

  4. LINUX进程内存占用情况如何查看的方法

    在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况.运行 top 命令后,CPU 使用状态会 ...

  5. Linux 进程内存布局(一)

    Linux 进程内存布局 内存管理是操作系统的核心分部,对于程序员和系统管理员来说都非常重要. 这篇文章中我将以介绍一个运行在x86架构的32位Linux 操作系统上进程为例,介绍进程在执行的时候的内 ...

  6. linux 进程 内存 耗光,Linux内存耗尽原因分析

    Linux内存的使用需要维持在一定的比例内,如果内存占用太高,系统也能运行,但是会影响速度.本文就来介绍一下Linux中内存耗尽应该怎么分析? 在测试NAS性能,用fstest长时间写,分析性能变差的 ...

  7. Linux进程管理四大工具ps \dstat\ top\ htop

    Linux进程管理之"四大名捕" 一.四大名捕 四大名捕,最初出现于温瑞安创作的武侠小说,是朝廷中正义力量诸葛小花的四大徒弟,四人各怀绝技,分别是轻功暗器高手"无情&qu ...

  8. linux+查内存数量,检查 Linux 中内存使用情况的 8 条命令 | Linux 中国

    作为一名 Linux 管理员,知道如何获取当前可用的和已经使用的资源情况,比如内存.CPU.磁盘等,是相当重要的. -- Magesh Maruthamuthu Linux 并不像 Windows,你 ...

  9. linux top VIRT RES SHR SWAP DATA内存参数详解

    Linux top VIRT RES SHR SWAP DATA内存参数详解 其实很早之前就想开博客,写一写码农几年自己积攒下来的知识与见解.看过很多文章有过很多感触,有些收获很值得梳理一下认真思考反 ...

最新文章

  1. 9月第1周安全回顾 IM安全威胁严重 企业增加无线安全投入
  2. 清华旷视:让VGG再次伟大!
  3. 复合索引使用的先决条件
  4. Java案例-用户注册邮箱绑定激活功能实现
  5. centos7安装sftp服务器
  6. xp文件夹怎么设置密码?压缩文件及Office文件加密方法
  7. codeforces 816 B. Karen and Coffee(思维)
  8. iOS学习——ViewController(六)
  9. 《隐秘的角落》:发生在IDC机房的隐秘事件
  10. 前端性能优化分析(雅虎军规)
  11. Linux-CentOS7安装教程【附CentOS7镜像】
  12. W5500以太网控制器芯片(一):ioLibrary库实现TCP服务器
  13. 第十四章 C语言头文件的编写_C语言标准库以及标准头文件
  14. NPN和PNP三极管做开关电路
  15. 耐得住寂寞,守得住繁华
  16. Linux下同型号USB相机端口绑定
  17. dnf服务器炸团门票怎么找回,DNF最新BUG,玩家打团买票后材料消失,无法引炸直接退队!...
  18. Ajax入门(附学习案例)
  19. G711转AAC代码总结【转】
  20. ARM处理器体系结构总结

热门文章

  1. CVPR 2019 | 一种用于年龄估计的连续感知概率网络
  2. 2019年上半年收集到的人工智能AutoML干货文章
  3. 什么样的NLP库,可以支持53种语言?
  4. 人工智能项目的六投三不投
  5. 未来十年是AI的黄金发展期
  6. 预告丨2018年值得关注的200场机器学习会议
  7. csdn自带的在线编辑器如何让图片并排显示
  8. 新型智能头盔可快速评估患者中风的大小、位置和类型
  9. 由内而外:大脑是如何形成感官记忆的
  10. 【专家观点】刘经南院士:北斗+5G为何能引领新基建?