计算机中的硬件资源主要有三种:CPU, 内存 和 I/O 。进程为获得这些资源资源相互竞争,而操作系统(内核)则负责公平地分配资源。这里介绍一些linux系统下性能监控的简单方法。
Linux下进程与资源的利用详解
进程跟踪
ps命令
ps命令可以帮助我们查看系统中运行的进程。比如:
luo@luo-ThinkPad-Edge-E431:~$ ps
PID TTY TIME CMD
6653 pts/4 00:00:00 bash
6786 pts/4 00:00:00 ps
这是我电脑下的运行ps的输出结果,直接运行ps将输出该bash下的所有进程。其中每行的字段依次代表以下内容:
-
PID:进程ID。
- TTY:进程所在的终端设备。
- TIME:进程到目前为止所占用的CPU时长。
- CMD:命令名。
其中一些较为常用的命令选项:
ps x
:显示当前用户运行的所有进程。- ` ps ax`:显示当前系统下运行的所有进程,包括其他用户的进程。
ps u
:显示更详细的进程信息。ps m
:查看线程的信息。
top命令
ps命令虽然可以列出当前运行的进程,但是无法提供进程随时间变化的情况。为了了解进程占用cpu的时间和内存大小的变化情况,我们可以使用top
这样的命令。
下面是top命令的一部分输出结果:
top - 21:04:34 up 8:08, 1 user, load average: 0.22, 0.27, 0.25
Tasks: 247 total, 2 running, 245 sleeping, 0 stopped, 0 zombie
%Cpu(s): 6.5 us, 2.3 sy, 0.7 ni, 90.3 id, 0.3 wa, 0.0 hi, 0.0 si, 0
KiB Mem : 3859572 total, 346840 free, 1904620 used, 1608112 buff/cach
KiB Swap: 4006908 total, 3999524 free, 7384 used. 1402896 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+
5472 luo 20 0 1026076 193708 99844 S 13.0 5.0 10:20.77
5435 luo 20 0 1508752 284052 148468 S 9.0 7.4 6:52.68
4302 luo 20 0 1176400 147504 83072 S 7.3 3.8 2:40.21
1061 root 20 0 407488 68348 39068 S 5.3 1.8 6:52.82
第一段是一些系统的运行情况,包括任务数,任务状态,cpu使用率,内存以及交换空间使用情况等等。后面的表格则是以每一行列出了每一个进程。
一些字段的解释:
- PR和NI:表示进程优先级数。
- VIRT:表示进程占用的虚拟内存。
- RES:表示进程占用的实际物理内存。
- SHR:表示进程占用的共享内存。
在top命令运行期间,因为进程的情况是动态变化的,而top的输出内容也在动态的更新。同时top也可以在运行期间接受键盘输入命令:
空格键 :立即显示更新内容。
- M:按照当前内存使用量排序。
- T:按照当前CPU累计使用量排序。
- f:选择不同的统计信息来显示。
查看打开的文件
lsof命令
lsof命令可以列出打开的文件以及使用他们的进程,在UNIX系统下,文件是一个很重要的概念,所lsof是一个很有用的命令,它不仅仅显示常规文件,还显示网络资源,动态库以及管道等等。下面是lsof命令输出的一个片段。
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 8,2 4096 2 /
systemd 1 root rtd DIR 8,2 4096 2 /
systemd 1 root txt REG 8,2 1577232 21233907 /lib/systemd/systemd
systemd 1 root mem REG 8,2 18976 21233691 /lib/x86_64-linux-gnu/libuuid.so.1.3.0
一些不好理解的字段:
- FD:显示文件的作用。
- DEVICE:包含该文件的设备的主要代码和次要代码。
- NODE:文件的索引节点编号。
由于lsof命令的输出通常很长,虽然可以通过less等分页命令分页显示结果,但这样效率还是太低了。我们可以通过命令行选项来过滤输出结果。
使用命令名当参数的例子:
lsof /home/luo
这个命令显示 /home/luo 目录中所有打开的文件。
另外还可以根据PID列出打开的文件:
lsof -p pid
跟踪程序执行和系统调用
strace命令
系统调用跟踪的命令,使用它能够显示进程所涉及的所有系统调用。下面是strace命令输出的一个片段:
luo@luo-ThinkPad-Edge-E431:~$ strace cat /dev/null
execve("/bin/cat", ["cat", "/dev/null"], [/* 65 vars */]) = 0
brk(NULL) = 0xb8a000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6d56a81000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...
所谓系统调用,是操作系统留给应用程序的接口,是应用程序获取操作系统服务诸如打开文件,读取数据等等的唯一途径。
在UNIX系统中,一个进程若想启动另一个进程,该进程会使用fork()系统调用从自身创建出一个副本,然后副本调用exec()系统调用集来启动和运行新的程序。strace命令在fork()系统调用在之后开始监控新创建的进程。从上述输出结果我们可以看出这个过程的大概。
ltrace命令
ltrace命令跟踪对共享库的调用,共享库不属于内核级的内容,属于较高的层次,共享库比系统调用数量多得多,所以输出内容也比较多。可以加入命令选项过滤。
测量CPU时间
监控进程
如果想单独监控进程,可以使用top命令加-p选项,如下:
top -p pid
也可以使用time命令,比如:
time ls
会在ls执行完毕之后列出如下字段:
real 0m0.003s
user 0m0.000s
sys 0m0.000s
real指的是从程序开始到程序执行结束时所消耗的时间,包括CPU的用时和所有延迟程序执行的因素的总和。CPU用时被划分为user和sys两块。user表示程序本身,以及它所调用的库中的子例程使用的时间。sys是由程序直接或间接调用的系统调用执行的时间。
前面所说的两种监控进程的方法,都会不断的刷新输出结果,如果我们想查看进程在过去某个时间段内的资源使用情况,可以使用pidstat
命令。
下面是对进程10937的监控结果:
luo@luo-ThinkPad-Edge-E431:~$ pidstat -p 10937
Linux 4.4.0-38-generic (luo-ThinkPad-Edge-E431) 2016年10月04日 _x86_64_ (4 CPU)
19时16分41秒 UID PID %usr %system %guest %CPU CPU Command
19时16分41秒 1000 10937 0.00 0.00 0.00 0.00 3 bash
默认情况下它会显示用户时间和系统时间的百分比,一级综合的CPU时间爱呢百分比。使用-d
选项可以监控磁盘,-r
选项监控内存 。
Tips : 对于linux系统监控,还可以使用sar命令,它是linux下一个全面的系统活动报告命令 。
平均负载(load average)
平均负载是指准备就绪待执行的进程的平均数,也就是某一时刻就可以使用CPU的进程数的一个估计值。
使用uptime命令可以帮助我们查看系统平均负载的情况。
luo@luo-ThinkPad-Edge-E431:~$ uptime
13:02:31 up 46 min, 1 user, load average: 0.25, 0.27, 0.22
上面这段输出表示:内核已经运行了46分钟,有一个用户存在,过去一分钟,五分钟,十五分钟的平均负载分别是 0.25 , 0.27 , 0.22 。
使用vmstat监控CPU和内存性能
vmstat命令可以让我们清晰地了解内核交换内存页面的频率,CPU的繁忙程度以及IO的使用情况。
下面是vmstat 2
命令的输出结果,其中数字表示刷新的间隔秒数。
luo@luo-ThinkPad-Edge-E431:~$ vmstat 2
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 61640 254040 34724 2187808 0 4 116 107 294 1378 11 3 84 2 0
0 0 61640 259356 34724 2188176 0 0 64 0 277 1036 2 1 97 0 0
0 0 61640 260256 34732 2188176 0 0 0 6 275 1017 2 1 97 0 0
0 0 61640 261344 34732 2188220 0 0 64 260 286 1012 2 1 97 0 0
输出结果包括:procs(进程),memory(内存使用),swap(内存页面交换),io(磁盘使用),system(内核切换到内核代码的次数),cpu(系统各组件使用cpu的时间)。
内存(memory) 缓冲(Cache) 以及交换空间(swap)的简单比较:
内存: 程序在运行时,必须先调入内存,内存的读写速度比磁盘要快几个数量级。
缓冲:通常是为解决两个设备之间读写速度不匹配而设置的,比如内存和CPU之间的高速缓冲,或者内存和磁盘之间的缓冲区(磁盘缓冲)。
交换空间: 用作虚拟内存的硬盘部分被称为交换空间。虚拟内存是在磁盘上的一块区域,用于扩充主存的容量。虚拟内存 存放的数据是内核不常使用的信息,内存管理机制会把这些不常用的内存快保存到磁盘上,当要使用时才重新调入内存。
在linux下可以使用free 命令查看内存以及交换空间的使用情况。
I/O监控
使用iostat
如名所述,这是个专门针对 IO监控 的命令。
luo@luo-ThinkPad-Edge-E431:~$ iostat
Linux 4.4.0-38-generic (luo-ThinkPad-Edge-E431) 2016年10月04日 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
9.66 0.11 2.55 1.51 0.00 86.16
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 3.55 80.05 74.61 2076729 1935621
其中avg-cpu部分是CPU运行情况。Device部分的解释是:
- tps : 平均每秒的数据传输量。
- kB_read/s : 平均美妙数据读取量。
- kB_read : 数据读取总量。
iostat命令也可以通过在后面加数字设定刷新间隔。加入命令选项-p ALL
还可以显示磁盘所有分区的 I/O 情况 。
Tips : 可以使用类似于top的命令iotop来查看系统中各个进程对 I/O 资源的使用情况 。
最后说一下
针对 linux 下系统监控的工具有很多 ,一般来说看完上面这些就足够了。在你需要找出系统变慢占用资源最多的那个进程时,这些工具会变得很有用。
更多详细的内容,你可以参考 : Linux 工具参考