请教prstat 查看进程内存查看工具使用情况的问题

声明:现大部分文章为寻找问题时在网上相互转载,在此博客中做个记录,方便自己也方便有类似问题的朋友,故原出处已不好查到,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明。谢谢。
随笔- 443&
&&&&&&&&&&&
在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要。在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况。运行 top 命令后,CPU 使用状态会以全屏的方式显示,并且会处在对话的模式 -- 用基于 top 的命令,可以控制显示方式等等。退出 top 的命令为 q (在 top 运行中敲 q 键一次)。
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器
  可以直接使用top命令后,查看%MEM的内容。可以选择按进程查看或者按用户查看,如想查看oracle用户的进程内存使用情况的话可以使用如下的命令:  $ top -u oracle
内容解释:
  PID:进程的ID  USER:进程所有者  PR:进程的优先级别,越小越优先被执行  NInice:值  VIRT:进程占用的虚拟内存  RES:进程占用的物理内存  SHR:进程使用的共享内存  S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数  %CPU:进程占用CPU的使用率  %MEM:进程使用的物理内存和总内存的百分比  TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。  COMMAND:进程启动命令名称
  操作实例:
  在命令行中输入 &top&
  即可启动 top
  top 的全屏对话模式可分为3部分:系统信息栏、命令输入栏、进程列表栏。
  第一部分 -- 最上部的 系统信息栏 :
  第一行(top):
    &00:11:04&为系统当前时刻;
    &3:35&为系统启动后到现在的运作时间;
    &2 users&为当前登录到系统的用户,更确切的说是登录到用户的终端数 -- 同一个用户同一时间对系统多个终端的连接将被视为多个用户连接到系统,这里的用户数也将表现为终端的数目;
    &load average&为当前系统负载的平均值,后面的三个值分别为1分钟前、5分钟前、15分钟前进程的平均数,一般的可以认为这个数值超过 CPU 数目时,CPU 将比较吃力的负载当前系统所包含的进程;
  第二行(Tasks):
    &59 total&为当前系统进程总数;
    &1 running&为当前运行中的进程数;
    &58 sleeping&为当前处于等待状态中的进程数;
    &0 stoped&为被停止的系统进程数;
    &0 zombie&为被复原的进程数;
  第三行(Cpus):
    分别表示了 CPU 当前的使用率;
  第四行(Mem):
    分别表示了内存总量、当前使用量、空闲内存量、以及缓冲使用中的内存量;
  第五行(Swap):
    表示类别同第四行(Mem),但此处反映着交换分区(Swap)的使用情况。通常,交换分区(Swap)被频繁使用的情况,将被视作物理内存不足而造成的。
  第二部分 -- 中间部分的内部命令提示栏:
  top 运行中可以通过 top 的内部命令对进程的显示方式进行控制。内部命令如下表:
  - 改变画面更新频率
  l - 关闭或开启第一部分第一行 top 信息的表示
  t - 关闭或开启第一部分第二行 Tasks 和第三行 Cpus 信息的表示
  m - 关闭或开启第一部分第四行 Mem 和 第五行 Swap 信息的表示
  N - 以 PID 的大小的顺序排列表示进程列表(第三部分后述)
  P - 以 CPU 占用率大小的顺序排列进程列表 (第三部分后述)
  M - 以内存占用率大小的顺序排列进程列表 (第三部分后述)
  h - 显示帮助
  n - 设置在进程列表所显示进程的数量
  q - 退出 top
  改变画面更新周期
  第三部分 -- 最下部分的进程列表栏:
  以 PID 区分的进程列表将根据所设定的画面更新时间定期的更新。通过 top 内部命令可以控制此处的显示方式
可以根据进程查看进程相关信息占用的内存情况,(进程号可以通过ps查看)如下所示:  $ pmap -d 5647
  如下例所示:  $ ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'& 其中rsz是是实际内存  $ ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid' | grep oracle |& sort -nrk
  其中rsz为实际内存,上例实现按内存排序,由大到小
在Linux下查看内存我们一般用free命令:[root@scs-2 tmp]# free&&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&& 3266180&&& 3250004&&&&& 16176&&&&&&&&& 0&&&& 110652&&& 2668236-/+ buffers/cache:&&&& 471116&&& 2795064Swap:&&&&& 2048276&&&&& 80160&&& 1968116
下面是对这些数值的解释:total:总计物理内存的大小。used:已使用多大。free:可用有多少。Shared:多个进程共享的内存总额。Buffers/cached:磁盘缓存的大小。第三行(-/+ buffers/cached):used:已使用多大。free:可用有多少。第四行就不多解释了。区别:第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。 这两个的区别在于使用的角度来看,第一行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是16176KB,已用内存是3250004KB,其中包括,内核(OS)使用+Application(X, oracle,etc)使用的+buffers+cached.第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached。如上例:76+8236
接下来解释什么时候内存会被交换,以及按什么方交换。 当可用内存少于额定值的时候,就会开会进行交换。如何看额定值:cat /proc/meminfo
[root@scs-2 tmp]# cat /proc/meminfoMemTotal:&&&&& 3266180 kBMemFree:&&&&&&&& 17456 kBBuffers:&&&&&&& 111328 kBCached:&&&&&&& 2664024 kBSwapCached:&&&&&&&&& 0 kBActive:&&&&&&&& 467236 kBInactive:&&&&& 2644928 kBHighTotal:&&&&&&&&&& 0 kBHighFree:&&&&&&&&&&& 0 kBLowTotal:&&&&& 3266180 kBLowFree:&&&&&&&& 17456 kBSwapTotal:&&&& 2048276 kBSwapFree:&&&&& 1968116 kBDirty:&&&&&&&&&&&&&& 8 kBWriteback:&&&&&&&&&& 0 kBMapped:&&&&&&&& 345360 kBSlab:&&&&&&&&&& 112344 kBCommitted_AS:&& 535292 kBPageTables:&&&&&& 2340 kBVmallocTotal:
kBVmallocUsed:&&& 272696 kBVmallocChunk:
kBHugePages_Total:&&&& 0HugePages_Free:&&&&& 0Hugepagesize:&&&& 2048 kB
用free -m查看的结果:[root@scs-2 tmp]# free -m &&&&&&&&&&&& total&&&&&& used&&&&&& free&&&& shared&&& buffers&&&& cachedMem:&&&&&&&&& 3189&&&&&& 3173&&&&&&&& 16&&&&&&&&& 0&&&&&&& 107&&&&&& 2605-/+ buffers/cache:&&&&&&& 460&&&&&& 2729Swap:&&&&&&&& 2000&&&&&&&& 78&&&&&& 1921
查看/proc/kcore文件的大小(内存镜像):[root@scs-2 tmp]# ll -h /proc/kcore -r-------- 1 root root 4.1G Jun 12 12:04 /proc/kcore
占用内存的测量
测量一个进程占用了多少内存,linux为我们提供了一个很方便的方法,/proc目录为我们提供了所有的信息,实际上top等工具也通过这里来获取相应的信息。
/proc/meminfo 机器的内存使用信息
/proc/pid/maps pid为进程号,显示当前进程所占用的虚拟地址。
/proc/pid/statm 进程所占用的内存
[root@localhost ~]# cat /proc/self/statm
654 57 44 0 0 334 0
CPU 以及CPU0。。。的每行的每个参数意思(以第一行为例)为:
参数 解释 /proc//status
Size (pages) 任务虚拟地址空间的大小 VmSize/4
Resident(pages) 应用程序正在使用的物理内存的大小 VmRSS/4
Shared(pages) 共享页数 0
Trs(pages) 程序所拥有的可执行虚拟内存的大小 VmExe/4
Lrs(pages) 被映像到任务的虚拟内存空间的库的大小 VmLib/4
Drs(pages) 程序数据段和用户态的栈的大小 (VmData+ VmStk )4
dt(pages) 04
查看机器可用内存
/proc/28248/&free
total used free shared buffers cached
Mem: 400 668 503688
-/+ buffers/cache: 744
Swap: 08 1870312
我们通过free命令查看机器空闲内存时,会发现free的值很小。这主要是因为,在linux中有这么一种思想,内存不用白不用,因此它尽可能的cache和buffer一些数据,以方便下次使用。但实际上这些内存也是可以立刻拿来使用的。
所以 空闲内存=free+buffers+cached=total-used
top命令 是Linux下常用的性能 分析工具 ,能够实时显示系统 中各个进程的资源占用状况,类似于Windows的任务管理 器。下面详细介绍它的使用方法。
top - 02:53:32 up 16 days,& 6:34, 17 users,& load average: 0.24, 0.21, 0.24Tasks: 481 total,&& 3 running, 474 sleeping,&& 0 stopped,&& 4 zombieCpu(s): 10.3%us,& 1.8%sy,& 0.0%ni, 86.6%id,& 0.5%wa,& 0.2%hi,& 0.6%si,& 0.0%stMem:&& 4042764k total,& 4001096k used,&&& 41668k free,&& 383536k buffersSwap:& 2104472k total,&&&& 7900k used,& 2096572k free,& 1557040k cached
& PID USER&&&&& PR& NI& VIRT& RES& SHR S %CPU %MEM&&& TIME+& COMMAND32497 jacky&&&& 20&& 0& 669m 222m& 31m R&& 10& 5.6&&&&&& 29:27.62 firefox&4788 yiuwing&& 20&& 0& 257m& 18m& 13m S&&& 5& 0.5&&&&&&&&& 5:42.44 konsole&5657 Liuxiaof& 20&& 0& 585m 159m& 30m S&&& 4& 4.0&&&&&&&&& 5:25.06 firefox&4455 xiefc&&&&& 20&& 0& 542m& 124m& 30m R&&& 4& 3.1&&&&&&&& 7:23.03 firefox&6188 Liuxiaof& 20&& 0& 191m&& 17m& 13m S&&& 4& 0.5&&&&&&&&& 0:01.16 konsole&
统计信息区前五行是系统整体的统计信息。第一行是任务队列信息,同 uptime& 命令的执行结果。其内容如下:
01:06:48& 当前时间& up 1:22& 系统运行 时间,格式为时:分& 1 user& 当前登录用户 数& load average: 0.06, 0.60, 0.48& 系统负载 ,即任务队列的平均长度。&&&&&&&&&&& 三个数值分别为& 1分钟、5分钟、15分钟前到现在的平均值。&
第二、三行为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。内容如下:
Tasks: 29 total& 进程总数& 1 running& 正在运行的进程数& 28 sleeping& 睡眠的进程数& 0 stopped& 停止的进程数& 0 zombie& 僵尸进程数& Cpu(s): 0.3% us& 用户空间占用CPU百分比& 1.0% sy& 内核 空间占用CPU百分比& 0.0% ni& 用户进程空间内改变过优先级的进程占用CPU百分比& 98.7% id& 空闲CPU百分比& 0.0% wa& 等待输入输出的CPU时间百分比& 0.0% hi&&&& 0.0% si&&&&
最后两行为内存 信息。内容如下:
Mem: 191272k total& 物理内存总量& 173656k used& 使用的物理内存总量& 17616k free& 空闲内存总量& 22052k buffers& 用作内核缓存 的内存量& Swap: 192772k total& 交换区总量& 0k used& 使用的交换区总量& 192772k free& 空闲交换区总量& 123988k cached& 缓冲的交换区总量。&&&&&&&&&&& 内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,&&&&&&&&&&& 该数值即为这些内容已存在于内存中 的交换区的大小。&&&&&&&&&&& 相应的内存再次被换出时可不必再对交换区写入。&
进程信息区统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。
序号& 列名& 含义& a& PID& 进程id& b& PPID& 父进程id& c& RUSER& Real user name& d& UID& 进程所有者的用户id& e& USER& 进程所有者的用户名& f& GROUP& 进程所有者的组名& g& TTY& 启动进程的终端名。不是从终端启动的进程则显示为 ?& h& PR& 优先级& i& NI& nice值。负值表示高优先级,正值表示低优先级& j& P& 最后使用的CPU,仅在多CPU环境 下有意义& k& %CPU& 上次更新到现在的CPU时间占用百分比& l& TIME& 进程使用的CPU时间总计,单位秒& m& TIME+& 进程使用的CPU时间总计,单位1/100秒& n& %MEM& 进程使用的物理内存 百分比& o& VIRT& 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES& p& SWAP& 进程使用的虚拟内存中,被换出的大小,单位kb。& q& RES& 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA& r& CODE& 可执行代码占用的物理 内存大小,单位kb& s& DATA& 可执行代码以外的部分(数据 段+栈)占用的物理 内存大小,单位kb& t& SHR& 共享内存大小,单位kb& u& nFLT& 页面错误次数& v& nDRT& 最后一次写入到现在,被修改过的页面数。& w& S& 进程状态。&&&&&&&&&&& D =不可中断的睡眠状态&&&&&&&&&&& R =运行&&&&&&&&&&& S =睡眠&&&&&&&&&&& T =跟踪/停止&&&&&&&&&&& Z =僵尸进程& x& COMMAND& 命令名/命令行& y& WCHAN& 若该进程在睡眠,则显示睡眠中的系统函数名& z& Flags& 任务标志,参考 sched.h&
默认情况下仅显示比较重要的& PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND& 列。可以通过下面的快捷键来更改显示内容。更改显示内容通过 f 键可以选择显示的内容。按 f 键之后会显示列的列表,按 a-z& 即可显示或隐藏对应的列,最后按回车键确定。按 o 键可以改变列的显示顺序。按小写的 a-z 可以将相应的列向右移动,而大写的 A-Z& 可以将相应的列向左移动。最后按回车键确定。按大写的 F 或 O 键,然后按 a-z 可以将进程按照相应的列进行排序。而大写的& R 键可以将当前的排序倒转。
==============================
top命令使用过程中,还可以使用一些交互的命令来完成其它参数的功能。这些命令是通过快捷键启动的。<空格>:立刻刷新。P:根据CPU使用大小进行排序。T:根据时间、累计时间排序。q:退出top命令。m:切换显示内存信息。t:切换显示进程和CPU状态信息。c:切换显示命令名称和完整命令行。M:根据使用内存大小进行排序。W:将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。
可以看到,top命令是一个功能十分强大的监控系统的工具,对于系统管理员而言尤其重要。但是,它的缺点是会消耗很多系统资源。
&应用实例 使用top命令可以监视指定用户,缺省情况是监视所有用户的进程。如果想查看指定用户的情况,在终端中按&U&键,然后输入用户名,系统就会切换为指定用户的进程运行界面。a.作用free命令用来显示内存的使用情况,使用权限是所有用户。b.格式free [-b -k -m] [-o] [-s delay] [-t] [-V]c.主要参数-b -k -m:分别以字节(KB、MB)为单位显示内存使用情况。-s delay:显示每隔多少秒数来显示一次内存使用情况。-t:显示内存总和列。-o:不显示缓冲区调节列。d.应用实例free命令是用来查看内存使用情况的主要命令。和top命令相比,它的优点是使用简单,并且只占用很少的系统资源。通过-S参数可以使用free命令不间断地监视有多少内存在使用,这样可以把它当作一个方便实时监控器。#free -b -s5使用这个命令后终端会连续不断地报告内存使用情况(以字节为单位),每5秒更新一次。
阅读(...) 评论()
声明:现大部分文章为寻找问题时在网上相互转载,在此博客中做个记录,方便自己也方便有类似问题的朋友,故原出处已不好查到,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明。谢谢。1001人阅读
Solaris(1)
prstat:进程监控
下面将深入探讨 Solaris&&prstat(1),帮助了解系统效用的全面实用。
prstat – 全面的实用工具
Solaris 中最重要、使用最广的实用工具是 prstat(参见 prstat(1))。prstat 可以快速回答以下问题:
& & *系统占用了多少 CPU 和内存?
& & *系统效用了哪些进程(或、
zone 、项目、任务)?
& & *系统怎样使用进程/线程(用户绑定,I/O 绑定)?
在最简单的形式中,prstat &interval&(即 prstat 2)将所有进程并根据
CPU 使用率报告数据。
进程的顺序根据当前的 CPU 使用率从高(最多)到低(最少)排列(% - 100% 表示所有系统 CPU 都完全利用)。对于列表中的每个进程,将打印以下信息:
& & * PID:进程的进程 ID。
& & *USERNAME:真实用户(登录)名称或真实用户 ID。
& & *SIZE:进程的总虚拟内存大小,以 K、M 或 G 为单位。
& & *RSS:进程的驻留集大小 (RSS),以 K、M 或 G 为单位。
& & *STATE:进程的状态 (cpuN/sleep/wait/run/zombie/stop)。
& & *PRI:进程的优先级。数字更大表示优先级更高。
& & *NICE:优先级计算中使用的 nice 值。只有特定调度类中的进程才有 nice 值。
& & *TIME:进程的累计执行时间。
& & *CPU:进程使用的当前 CPU 时间的百分比。如果在非全局域中执行并且池设备是活动的,百分比将是 zone 绑定的池所使用的处理器集合中处理器的百分比。
& & *PROCESS:进程的名称(执行的名称)。
& & *NLWP:进程中 lwps 的数量。
prstat 的 &interval& 参数是采样/刷新的时间间隔(以秒为单位)。
专题报告 – 排序
除了 CPU 使用率之外,prstat 输出还可以按照其他指标排序。可以将 -s(降序)或 -S(升序)与指标选项一起使用(即 prstat -s time 2):
标准& &&&注释
cpu& && &按照 CPU 使用率排序。这是默认设置。
pri& && &&&按照进程优先级排序。
rss& && & 按照驻留集大小排序。
size& && &按照进程图像排序。
time& && &按照进程执行时间排序。
专题报告 – 连续模式
对 prstat 使用选项 -c,新的报告将打印在上一个报告的下方,而不是覆盖它。这在收集文件信息时非常有用(即 prstat -c 2 & prstat.txt)。选项 -n &number of output lines& 可以用来设置报告的最大长度。
专题报告 – 用户
对 prstat 使用 -a 或 -t 选项,将额外打印有关用户的报告。
专题报告 – zone&
对 prstat 使用 -Z 选项,将额外打印有关 zone 的报告。
专题报告 – 项目(参见 projects(1))
对 prstat 使用 -J 选项,将额外打印有关项目的报告。
专题报告 – 任务(参见 newtask(1))
对 prstat 使用 -T 选项,将额外打印有关任务的报告。
专题报告 – Microstate Accounting
与其他每个时间周期或每个固定时间间隔(通常为百分之几秒)收集 CPU 数据的操作系统不同,Solaris 10 合并了一种名为 Microstate Accounting 的技术,可以使用高分辨率时间戳测量每个时间的 CPU 数据,从而生成更为准确的数据统计。
Microstate Accounting 系统为线程和 CPU 维护准确的时间计数器。基于线程的 Microstate Accounting 跟踪每个线程中几个有意义的状态,以及用户和系统时间,包括陷阱时间、锁定时间、睡眠时间和等待时间。prstat 按进程(选项 -m)或线程(选项 -mL)报告微观状态。
prstat 使用场景
prstat 使用场景 – cpu 时延问题
测量 CPU 饱和度的一个重要方法是 prstat 的时延问题(LAT 列)输出。我们使用两个 CPU 密集型应用程序副本(cc_usr)
prstat – 使用 CPU 密集型应用程序观察时延问题
现在运行 prstat Microstate Accounting 报告,即 prstat -m 2 并记录输出:
prstat – prstat -m 2 输出
请观察最上面两行输出 PID 2223 和 PID 2224。可以清楚地看到两个流程的 LAT 微观状态(CPU 时延问题)都有较高的时间百分比(分别是 50% 和 52%)。其余时间如期花费在消耗方面(USR 微观状态)。此例清楚的表明,CPU 绑定应用程序争夺测试系统中惟一的一个 CPU,导致为访问 CPU 需要很长的等待时间(时延问题)。
prstat 使用场景 – 高系统时间
现在运行系统调用集中型应用程序(cc_sys)并观察 prstat 的输出。首先,启动一个 cc_sys 实例:
# cc_sys &
prstat – 系统调用集中型应用程序
然后观察 prstat -m 2 输出:
prstat – prstat -m 2,系统调用集中型应用程序的输出
注意最上方 PID 2310 那一行。清楚地发现流程 cc_sys 占用了高系统时间使用率 (61%)。还可以发现 ICX/VCX (277/22) 的比率很高,这说明该进程经常无意识关闭 CPU。
prstat 使用常见
prstat 使用常见 – 过度锁定
经常可以看到,多处理器系统上应用程序的扩展性很差。根本原因之一可能在于,应用程序中的锁定设计很差,导致在同步时的等待时间过长。prstat 列 LCK 报告等待用户锁定花费的时间。
我们看一个示例,一个示例程序实现了关键段的锁定机制,使用的是读/写锁定。该程序有 4 个线程需要访问共享的关键 zone 以进行读取,还有一个线程以写模式访问关键段。为了说明问题所在,有意减慢了写入器的速度,以便它会占用关键段一段时间(对于读取器这是有效的障碍)。
首先启动程序,比如写入器在关键段中花费了 0 毫秒(理想情况)。
# cc_lck 0 &
writer will sleep 0 useces
cc_lck 0 – 在理想情况下运行
现在观察每个线程的微观状态。使用 prstat -mL -p 2626 2。
cc_lck 0 – prstat 输出
可以看到,所有 5 个线程几乎争夺到了相等的计算机资源。因为不管是读取器还是写入器都没有占用关键段很长的时间,没有记录等待时间。
现在重新执行整个测试,写入器将等待 10 毫秒。
# cc_lck 10 &
writer will sleep 10 useces
现在再次观察微观状态。使用 prstat -mL -p 2656 2。
cc_lck 10 – prstat 输出
这次情况似乎不太一样了。有 4 个线程在等待关键段的锁定期间花费的时间占总时间的 84%。另一方面,写入器 (LWP #1) 有 (82%) 的时间在休眠。
在本例的应用程序中,如果查看源代码会发现存在明显的锁定问题,prstat Microstate Accounting 功能将帮助找出较大程序的锁定弱点.
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:69754次
排名:千里之外
转载:99篇
(1)(1)(3)(1)(1)(3)(1)(3)(4)(2)(5)(3)(4)(4)(6)(5)(8)(2)(18)(4)(4)(1)(14)(6)(1)在linux下,使用top,ps等命令查看进程的内存使用情况时,经常看到VIRT,RES,SHR等,他们都代表什么意思呢?不同的大小对进程有什么影响呢?这篇文章将来聊一聊这个问题。阅读本篇前建议先阅读,了解一些Linux下内存的基本概念,如什么是anonymous和file backed映射等。
查看进程所使用的内存
在进程的眼里,所有的内存都是虚拟内存,但是这些虚拟内存所对应的物理内存是多少呢?正如我们在中所介绍的那样,并不是每块虚拟内存都有对应的物理内存,可能对应的数据在磁盘上的一个文件中,或者交换空间上的一块区域里。一个进程真正的物理内存使用情况只有内核知道,我们只能通过内核开放的一些接口来获取这些统计数据。
先看看top的输出(top用到的数据来自于/proc/[pid]/statm),这里只是摘录了几条数据:
SHR S %CPU %MEM
TIME+ COMMAND
0:02.69 kworker/0:0
0:00.02 top
0:00.02 bash
VIRT:进程所使用的虚拟内存大小
RES:系统为虚拟内存分配的物理内存大小,包括file backed和anonymous内存,其中anonymous包含了进程自己分配和使用的内存,以及和别的进程通过mmap共享的内存;而file backed的内存就是指加载可执行文件和动态库所占的内存,以及通过private方式调用mmap映射文件所使用的内存(当在内存中修改了这部分数据且没有写回文件,那么这部分内存就变成了anonymous),这部分内存也可能跟别的进程共享。
SHR:RES的一部分,表示和别的进程共享的内存,包括通过mmap共享的内存和file backed的内存。当通过prive方式调用mmap映射一个文件时,如果没有修改文件的内容,那么那部分内容就是SHR的,一旦修改了文件内容且没有写回文件,那么这部分内存就是anonymous且非SHR的。
%MEM:等于RES/total*100%,这里total指总的物理内存大小。
注意:由于SHR可能会被多个进程所共享,所以系统中所有进程的RES加起来可能会超过总的物理内存数量,由于同样的原因,所有进程的%MEM总和可能超过100%。
从上面的分析可以看出,VIRT的参考意义不大,它只能反应出程序的大小,而RES也不能完全的代表一个进程真正占用的内存空间,因为它里面还包含了SHR的部分,比如三个bash进程共享了一个libc动态库,那么libc所占用的内存算谁的呢?三个进程平分吗?如果启动一个bash占用了4M的RES,其中3M是libc占用的,由于三个进程都共享那3M的libc,那么启动3个bash实际占用的内存将是3*(4-3)+3=6M,但是如果单纯的按照RES来算的话,三个进程就用了12M的空间。所以理解RES和SHR这两个数据的含义对我们在评估一台服务器能跑多少个进程时尤其重要,不要一看到apache的进程占用了20M,就认为系统能跑的apache进程数就是总的物理内存数除以20M,其实这20M里面有可能有很大一部分是SHR的。
注意:top命令输出中的RES和pmap输出中的RSS是一个东西。
上面top命令只是给出了一个进程大概占用了多少的内存,而pmap能更详细的给出内存都是被谁占用了。pmap命令输出的内容来自于/proc/[pid]/maps和/proc/[pid]/smaps这两个文件,第一个文件包含了每段的一个大概描述,而后一个文件包含了更详细的信息。
这里用pmap看看当前bash的内存使用情况,:
#这里$$代表当前bash的进程ID,下面只显示了部分输出结果
dev@dev:~$ pmap
976K r-x-- bash
4K r---- bash
36K rw--- bash
1544K rw---
2912K r---- locale-archive
1792K r-x-- libc-2.23.so
2044K ----- libc-2.23.so
16K r---- libc-2.23.so
8K rw--- libc-2.23.so
152K r-x-- ld-2.23.so
28K r--s- gconv-modules.cache
4K r---- ld-2.23.so
4K rw--- ld-2.23.so
00007ffde903a000
132K rw---
00007ffde90e4000
00007ffde90e6000
ffffffffff600000
这里第一列是内存的起始地址,第二列是mapping的地址大小,第三列是这段内存的访问权限,最后一列是mapping到的文件。这里的地址都是虚拟地址,大小也是虚拟地址大小。
这里的输出有很多的[ anon ]行,表示在磁盘上没有对应的文件,这些一般都是可执行文件或者动态库里的bss段。当然有对应文件的mapping也有可能是anonymous,比如文件的数据段。关于程序的数据段和bss段的介绍请参考。
上面可以看到bash、libc-2.23.so等文件出现了多行,但每行的权限不一样,这是因为每个动态库或者可执行文件里面都分很多段,有只能读和执行的代码段,有能读写的数据段,还有比如这一行“3b000
[ anon ]”,就是它上面一行libc-2.23.so的bss段。
[ stack ]表示进程用到的栈空间,而heap在这里看不到,因为pmap默认情况下不单独标记heap出来,由于heap是anonymous,所以从这里的大小可以推测出来,heap就是“be4000
1544K rw---
[ anon ]”。
其实从上面的结果根本看不出实际上每段占用了多少物理内存,要想看到RSS,需要使用-X参数,下面看看更详细的输出:
dev@dev:~$ pmap -X $$
Address Perm
Offset Device
Pss Referenced Anonymous Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked Mapping
fc:00 390914
006f3000 r--p 000f3000
fc:00 390914
006f4000 rw-p 000f4000
fc:00 390914
006fd000 rw-p :00
00be4000 rw-p :00
7f1fa0e9e000 r--p
0 locale-archive
7f1fa1176000 r-xp
fc:00 92 1512
0 libc-2.23.so
7f1fa1336000 ---p 001c0000
0 libc-2.23.so
7f1fa1535000 r--p 001bf000
fc:00 521726
0 libc-2.23.so
7f1fa1539000 rw-p 001c3000
fc:00 521726
0 libc-2.23.so
7f1fa153b000 rw-p :00
7f1fa196c000 r-xp
fc:00 521702
0 ld-2.23.so
7f1fa1b7e000 r--s
fc:00 132738
0 gconv-modules.cache
7f1fa1b85000 rw-p :00
7f1fa1b8f000 rw-p :00
7f1fa1b91000 r--p
fc:00 521702
0 ld-2.23.so
7f1fa1b92000 rw-p
fc:00 521702
0 ld-2.23.so
7f1fa1b93000 rw-p :00
7ffde903a000 rw-p :00
7ffde90e4000 r--p :00
7ffde90e6000 r-xp :00
ffffffffff600000 r-xp :00
0 [vsyscall]
===== ==== ==== ========== ========= ============== =============== ==== ======= ======
权限字段多了一个s和p的标记,s表示是和别人共享的内存空间,读写会影响到其他进程,而p表示这是自己私有的内存空间,读写这部分内存不会对其他进程造成影响。
输出标示出了[heap]段,并且也说明了后面几个[anon]代表的什么意思(vvar,vdso,vsyscall都是映射到内核的特殊段),mapping字段为空的都是上一行mapping文件里面的bss段(可是gconv-modules.cache后面有两行anonymous mapping,可能跟共享内存有关系,没有深究)。
Anonymous列标示出了哪些是并且有多少是Anonymous方式映射的物理内存,其大小小于等于RSS
RSS列表示实际占用的物理内存大小
top命令输出的SHR内存
最后来看看top命令输出的SHR到底由pmap的哪些输出构成
dev@dev:~$ pmap -d $$
Kbytes Mode
976 r-x-- 0000 0fc:00000 bash
4 r---- f3000 0fc:00000 bash
36 rw--- f4000 0fc:00000 bash
24 rw--- 00
1544 rw--- 00
16 rw--- 00
8 rw--- 00
4 r---- 5000 0fc:00000 ld-2.23.so
4 rw--- 6000 0fc:00000 ld-2.23.so
4 rw--- 00
00007ffc5a94b000
132 rw--- 00
00007ffc5a9b7000
8 r---- 00
00007ffc5a9b9000
8 r-x-- 00
ffffffffff600000
4 r-x-- 00
mapped: 22464K
writeable/private: 1848K
shared: 28K
dev@dev:~$ top -p $$
SHR S %CPU %MEM
TIME+ COMMAND
0:00.02 bash
从上面的输出可看出SHR ≈ RES - writeable/private,其中writeable/private主要包含stack和heap以及可执行文件和动态库的data和bss段,而stack+heap=5,这已经占了绝大部分,从而data和bss段之类的基本上可以忽略了,所以一般情况下,SHR ≈ RES - [heap] - [stack],由于stack一般都比较小,上面的等式可以进一步约等于:SHR ≈ RES - [heap]。
top命令能看到一个进程占用的虚拟内存空间、物理内存空间以及和别的进程共享的物理内存空间,这里共享的空间包括通过mmap共享的内存以及共享的可执行文件以及动态库。而mmap命令能看到更详细的信息,比如可执行文件和它所链接的动态库大小,以及物理内存都是被哪些段给占用了。
进程占用的虚拟地址空间大小跟程序的规模有关,除了stack和heap段,其他段的大小基本上都是固定的,并且在程序链接的时候就已经确定了,所以基本上只要关注stack和heap段就可以了,由于stack相对heap来说很小,所以只要没什么stack异常,只需要关注heap。
在实际的工作过程中,其实我们更关心的是RSS用了多少,都被谁用了,简单点说,如果我们没有同时启动多个进程(同一个程序),RSS就是一个很好的实际物理内存使用参考值,但如果是像apache那样同时跑很多个进程,那么RSS减去SHR所占用的空间就是一个很好的实际物理内存占用参考值,当然这都是大概估算值。
要想精确评估一个进程到底占了多少内存,还是很难的,需要对进程的每个段有深入的理解,尤其是SHR部分都有哪些进程在一起共享,不过现在服务器上的内存都是以G为单位的,所以一般情况下大概的估算一下加上合理的测试就能满足我们的需求了。
你可能感兴趣的文章
2 收藏,677
1 收藏,118
4 收藏,2.7k
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
分享到微博?
技术专栏,帮你记录编程中的点滴,提升你对技术的理解收藏感兴趣的文章,丰富自己的知识库
明天提醒我
我要该,理由是:
扫扫下载 App}

我要回帖

更多关于 查看进程占用内存 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信