Linux下高效的使用 top 命令(2)

C.快熟还是缓慢更新?

  在回答这个问题之前,让我们先简单介绍一下,Top 是如何运行的。这里,Strace 能够帮助你:

$ strace -o /tmp/trace.txt top -b -n 1

  使用你偏爱的文本编辑器打开 /tmp/trace.txt。你怎么想?一次调用有太多的活要做了,反正我是这么想的。Top 在每次遍历中必做的工作之一就是打开很多文件,并解析其内容,可以看看次数:

$ grep open( /tmp/hasil.txt | wc -l

  举例而言,我的 Linux 中,这个数量是304.仔细观察就会发现,Top 遍历 /proc 文件夹,以收集进程信息。/proc 本身是一个虚拟文件系统,意味着它并非存在于真实硬盘之中,而是由 Linux 内核凭空创建,保存在内存中的。在文件夹中,如/proc/2097(2097为 PID),Linux 内核将与之关联的信息打印到此文件中,而这里就是 Top 的消息来源。

  同时试一下:

$ time top -b -n 1

  这样你就能了解到 Top 单轮工作有多快了。在我的系统中,大约为0.5-0.6秒。看“real”字段,不是“user”或“system”字段,因为“real”字段反应了 Top 工作需要的总时间。

  所以,有了这个认知之后,使用适度的更新间隔是明智的。基于文件系统访问内存也是需要时间的。经验法则是,对于多数用户来说,1到3秒的间隔就足够了。在命令行中使用-d,或在交互模式下按下“s”以设置。你可以使用类似2.5,4.1这样的小树。

  什么时候我们需要快于1秒的更新?

时间段内需要更多的样本。应对这点要求,最好使用批处理模式,并将标准输出重定向到文件中,以便更好的分析。

你并不在意 Top 消耗的额外CPU负荷。是的,虽然它很小,它依然需要负荷。如果你的 Linux 系统相对比较空闲,随意使用短间隔,如果不是,最好为重要的任务保留你的 CPU 时间。

  一个减少 Top 工作的办法是只监测特定的几个 PID。这样,Top 无需遍历 /proc 下所有的子文件夹。用户名过滤呢?并不会变得更好。用户名过滤会给Top带来额外工作量,因此将其与短间隔联合将会增加 CPU 负荷。

  当然,当你需要强制更新时,按下 Space 键,Top 将会刷新统计。

D.我们需要的字段

  默认时,Top 启动后会显示下面的任务属性:

字段描述
PID :   进程 ID  
USER :   有效用户 ID  
PR :   动态优先值  
NI :   良好值,也被称为基本优先级  
VIRT :   任务虚拟大小。包括进程的可执行二进制文件大小,数据区大小以及所有已加载的共享库的大小。  
RES :   目前任务内存消耗。存入交换分区的部分并不包含。  
SHR :   一些内存区域可能由两个或多个任务分享,此字段反应这些共享区域。例如共享库以及 Sysv 共享内存。  
S :   任务状态  
%CPU :   Top 屏幕更新时专用于运行任务的CPU 时间百分比。  
%MEM :   任务当前内存消耗的百分比  
TIME+ :   在任务启动后消耗的总CPU时间。"+" sign means it is displayed with hundreth of a second granularity. 默认时,TIME/TIME+ 不会计入已经关闭的任务子进程。  
COMMAND :   显示程序名。  

  不止这些。下面我介绍一些你可能会用到的列:

列描述
nFLT ('u'键)  

进程启动以来重大页面错误(page fault)的个数。准确地说,页面错误是由于进程访问它的地址空间内不存在的页面引起的。“重大”的页面错误是指内核需要访问磁盘来使得该页面有效。相反,小型页面错误是指内核只需要在内存中分配页面而不用读磁盘。

例如,假设程序ABC的大小为8KB,页面大小为4KB。当程序读进内存的时候,发生了两次重大的页面错误(2*4KB)。程序本身分配了8KB空间当作临时数据。因此,还会有两次小型页面错误。

nFLT过高可能意味着:

进程从磁盘读取大量资源。The task is aggressively load some portions of its executable or library from the disk.

进程访问了一个已经交换到磁盘的页面。

当进程第一次运行时,看到大量重大页面错误很正常。下次运行的时候,由于缓存已经分配好了,你很可能看到"0"次或者很小的 nFLT。但是,如果一个程序频繁地触发重大页面错误,很有可能是你目前安装的内存不够那个程序使用。

 
nDRT ('v')  

上次页面写入磁盘以来,脏页面的数目。

什么是脏页面?先看一点背景知识。大家都知道,Linux使用了缓存系统,所以从磁盘读取的数据也会被缓存到内存中。这样做的优点是,后续的对这个磁盘块的读操作可以直接从内存中取数据,因而速度更快。

但这也是有代价的。如果缓冲区的内容被修改了,那么就需要进行同步。因此,被更改的缓冲区(脏页面)必需写回到磁盘中。同步失败则可能导致磁盘上的数据不一致。

在负载不重的系统中,nDRT 通常小于10(大约估计)或者为0。如果你的系统通常大于10,则有可能:

进程正在往磁盘写入大量数据。磁盘I/O经常跟不上缓冲区的速度。

磁盘I/O拥塞,因此即使进程修改了很小部分文件,也必需等待一段时间才能完成同步。拥塞出现在很多进程同时访问磁盘而缓存命中率低的情况下(译者注:FTP服务的典型情况)。

现在的话,(1) 不太可能出现,因为I/O速度越来越快,需要更少的CPU(DMA技术的出现)。所以 (2) 出现的概率更高。

注意:在 2.6.x 内核中, 不知道为什么,这个列的值总是0。

 
P ('j')  

上次使用的CPU。这个列只在SMP环境中有意义。这里的SMP指超线程,多核或者多CPU架构。如果你只有一个CPU(不是多核,没有超线程),这个列总是显示0。

在SMP系统中,即使这个列有几次改变,也不要吃惊。这意味着,Linux 内核尝试将你的进程移到另一个负载更少的CPU。

 
CODE ('r') 和 DATA ('s')  

CODE 只是反映了你程序代码的大小,DATA反映了你数据段(栈,堆,变量,不包含共享库) 的大小。单位都是KB。

DATA可以显示你的程序分配了多少内存。有时,也可以用来协助分析内存泄漏。当然,你需要更好的工具,如使用 valgrind 来查看每次的内存分配。如果DATA不断增长,则很有可能出现了内存泄漏。

注意:DATA, CODE, SHR, SWAP, VIRT, RES 都是使用页面大小(Intel架构上为4KB)来衡量。只读数据段也包含在CODE的大小中,因而有时候CODE比实现的段要大。

 
SWAP ('p')  

已经进行交换的进程内存映像大小。这个列有时很让人疑惑:

逻辑上,你可能期望这个列显示你的程序实际上是完全进行交换,还是部分交换了,交换了多少。但是事实上不是。即使"Swap used" 列显示为0,你仍然可以很吃惊地发现所有进程的SWAP列都大于0。到底是为什么呢?

这是由于 top 命令使用如下的计算公式:

VIRT = SWAP + RES or equal SWAP = VIRT - RES

前面说过,VIRT 包含了进程的地址空间里面的所有东西:内存中的,已经进行交换的,尚未从磁盘读取的。RES 代表了进程占用的全部内存大小。所以,这里的SWAP代表了已经进行交换的全部数据,以及尚未从磁盘读取的数据。不要被SWAP这个名字迷惑了,它代表的 不只是已经交换的数据。

 

  要显示以上的列,在交互模式下按 'f' 键,然后再按相应的键。按一下显示指定的列,再按一下隐藏该列。要确定当前显示的是哪些列,只需看第一行的字母(在"Current Fields"的右边)。大写字母表示显示了该列,小写表示隐藏。你选好以后,按回车即可。

  排序使用了类似的方法。按 'O' (大写),然后再按相应的键。即使记不住那些按键也没关系,top 会显示出来。新的排序键将标上星号,相应的字母会变成大写,很直观。选好以后,记得按回车。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/19977.html