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, htop资源管理器命令中的VIRT列和RES列的区别 Linux运维都知道,VIRT是虚拟内存,RES是物理内存 但是如何在VIRT中申请内存,如何在RES中申请内存,你知道吗?你以为只是malloc,new这么简单吗? 奉上我作的...
Linux下看内存和CPU使用率一般都用top命令,但是实际在用的时候,用top查看出来的内存占用率都非常高,如: Mem: 4086496k total, 4034428k used, 52068k free, ... PID USER PR NI VIRT RES SHR S %CP
离线安装包,亲测可用
使用secureCRT运行virt-manager显示虚机,要在secureCRT上打开X11功能
下载源地址:http://linuxsoft.cern.ch/cern/updates/slc63/x86_64/RPMS/repoview/virt-manager.html,qq电脑管家安全扫描无毒,解决CentOS 6.5 Virt-Manager启动出错:unsupported format character ‘��0...
windows下的virt-viewer工具,可以在windows下连接kvm虚拟机
virt-viewer-x64-0.5.7
virt-viewer-0.6.0 云计算 virt-viewer。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 755 root 20 0 0 0 0 S 33.4 0.0 1843:15 FLUSH 754 root 20 0 0 0 0 R 28.1 0.0 1717:29 CMPLT 756 root 20 0 0 0 0 D 10.6 0.0 608:50.53 BKGND 本...
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 755 root 20 0 0 0 0 S 33.4 0.0 1843:15 FLUSH 754 root 20 0 0 0 0 R 28.1 0.0 1717:29 CMPLT 756 root 20 0 0 0 0 D 10.6 0.0 608:50.53 BKGND
virt-manager linux虚拟机管理图型界面
Virt-manager虚拟化技术介绍.pdf
virt-manager是用于管理KVM虚拟环境的主要工具,virt-manager默认设置下需要使用root用户才能够使用该工具。当你想在KVM hypervisor服务器上托管虚拟机,由最终用户而非root用户访问这些虚拟机时并不总是很便利。
TOP命令(最后操作) TOP是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示...
xdisp_virt-master_h264远程桌面_xdisp_virt_xdisp_opera_远程桌面.zip
virt2phys内核驱动安装与下载
首先介绍top中一些字段的含义: VIRT:virtual memory usage 虚拟内存 1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等 2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而...
1.基于Virt-Viewer 2.0源码编译; 2.支持虚拟机USB重定向;
2.打开终端输入virt-manager命令启动virt-manager虚拟机管理界面 #virt-manager 3.通过virt-manager安装CentOS 6.6的虚拟机 点击如图所示图标新建虚拟机: 选择PXE引导,我的网络内存在一个系统自动化部署服务器:...