1、前言
作为后台程序员,经常和系统打交道,自己的程序也跑在系统中,有时候运行一段时间后会发现系统莫名奇妙就很卡,这个时候需要一些手段来判断到底是什么原因导致系统运行慢,是cpu占用高?内存不够?磁盘读写io阻塞还是程序本身逻辑问题?等等。下面就来一一分析。
1.1 概念定义
VIRT:virtual memory usage 虚拟内存
1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等
2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量
VIRT=SWAP+RES
RES:resident memory usage 常驻内存
1、进程当前使用的内存大小,但不包括swap out
2、包含其他进程的共享
3、如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反
4、关于库占用内存的情况,它只统计加载的库文件所占内存大小
RES = CODE + DATA
SHR:shared memory 共享内存
1、除了自身进程的共享内存,也包括其他进程的共享内存
2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小
3、计算某个进程所占的物理内存大小公式:RES – SHR
4、swap out后,它将会降下来
DATA
1、数据占用的内存。如果top没有显示,按f键可以显示出来。
2、真正的该程序要求的数据空间,是真正在运行中要使用的。
VIRT 虚拟内存中含有共享库、共享内存、栈、堆,所有已申请的总内存空间。
RES 是进程正在使用的内存空间(栈、堆),申请内存后该内存段已被重新赋值。
SHR 是共享内存正在使用的空间。
SWAP 交换的是已经申请,但没有使用的空间,包括(栈、堆、共享内存)。
DATA 是进程栈、堆申请的总空间。
2、系统信息采集
top
输入top命令后,可以按字母键实现显示:
N – 以 PID 的大小的顺序排列表示进程列表
P – 以 CPU 占用率大小的顺序排列进程列表
M – 以内存占用率大小的顺序排列进程列表
h – 显示帮助
n – 设置在进程列表所显示进程的数量
q – 退出 top
s – 改变画面更新周期
NI 是优先值,是用户层面的概念, PR是进程的实际优先级, 是给内核(kernel)看(用)的。
一般情况下,PR=NI+20, 如果一个进程的优先级PR是20, 那么它的NI(nice)值就是20-20=0。
NICE值应该是熟悉Linux/UNIX的人很了解的概念了,它是反应一个进程“优先级”状态的值,其取值范围是-20至19,一共40个级别。
这个值越小,表示进程”优先级”越高,而值越大“优先级”越低。
top -p pid查看指定进程
top -c 显示进程运行命令路径
top -H -p pid命令查看进程内各个线程占用的CPU百分比
第1行:系统运行时间和平均负载
load average数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU的数量,结果高于5的时候就表明系统在超负荷运转了。
- 注:这里显示数据是所有cpu的平均值,如果想看每一个cpu的处理情况,按1即可;折叠,再次按1;
第2行:任务
其中处于运行中的有1个,143个在休眠(sleep),stoped状态的有0个,zombie状态(僵尸)的有0个
第3行:cpu占用
%id:空闲CPU时间百分比,如果这个值过低,表明系统CPU存在瓶颈;
%wa:等待I/O的CPU时间百分比,如果这个值过高,表明IO存在瓶颈;
这里显示不同模式下所占cpu时间百分比,这些不同的cpu时间表示:
- us, user: 运行(未调整优先级的) 用户进程的CPU时间
- sy,system: 运行内核进程的CPU时间
- ni,niced:运行已调整优先级的用户进程的CPU时间
- wa,IO wait: 用于等待IO完成的CPU时间
- hi:处理硬件中断的CPU时间
- si: 处理软件中断的CPU时间
- st:这个虚拟机被hypervisor偷去的CPU时间(译注:如果当前处于一个hypervisor下的vm,实际上hypervisor也是要消耗一部分CPU处理时间的)。
第4、5行内存使用
第一行是物理内存使用,第二行是虚拟内存使用(交换空间)。
物理内存显示如下:全部可用内存、已使用内存、空闲内存、缓冲内存。相似地:交换部分显示的是:全部、已使用、空闲和缓冲交换空间。
实际可用内存=第四行的free + 第四行的buffers + 第五行的cached
对于内存监控,在top里我们要时刻监控第五行swap交换分区的used,如果这个数值在不断的变化,说明内核在不断进行内存和swap的数据交换,这是真正的内存不够用了。
如果是因为缺少内存,系统响应变慢很明显,因为这使得系统不停的做换入换出的工作;
sar
sar -u 1 2 采集cpu使用率,每秒采样一次,总共采样2次
sar -q 1 2 采集cpu平均负载
sar -r 1 2 采集内存使用率
sar -W 1 2 查看页面交换
可用top代替。
sar -n DEV 可以统计网络接口收发包。
vmstat
vmstat 1 3 采集cpu、内存
可用top代替。
iostat
如果IO存在性能瓶颈,top工具中的%wa会偏高;
进一步分析使用iostat工具:
iostat -d -x -k 1 1 -k kb显示,-x 显示更多,
- rrqm/s: 每秒进行 merge 的读操作数目。即 rmerge/s
- wrqm/s: 每秒进行 merge 的写操作数目。即 wmerge/s
- r/s: 每秒完成的读 I/O 设备次数。即 rio/s
- w/s: 每秒完成的写 I/O 设备次数。即 wio/s
- rsec/s: 每秒读扇区数。即 rsect/s
- wsec/s: 每秒写扇区数。即 wsect/s
- rkB/s: 每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。
- wkB/s: 每秒写K字节数。是 wsect/s 的一半。
- avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区)。
- avgqu-sz: 平均I/O队列长度。
- await: 平均每次设备I/O操作的等待时间 (毫秒)。
- svctm: 平均每次设备I/O操作的服务时间 (毫秒)。
- %util: 一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比
- 如果%iowait的值过高,表示硬盘存在I/O瓶颈。
- 如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。
- 如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;
- 如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。
- 如果avgqu-sz比较大,也表示有大量io在等待。
参数:
- -c 显示CPU使用情况
- -d 显示磁盘使用情况
- -k 以 KB 为单位显示
- -m 以 M 为单位显示
- -N 显示磁盘阵列(LVM) 信息
- -n 显示NFS 使用情况
- -p[磁盘] 显示磁盘和分区的情况
- -t 显示终端和CPU的信息
- -x 显示详细信息
- -V 显示版本信息
- tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.)。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。
- kB_read/s:每秒从设备(drive expressed)读取的数据量;
- kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
- kB_read:读取的总数据量;kB_wrtn:写入的总数量数据量;
形象的比喻:
- r/s+w/s 类似于交款人的总数
- 平均队列长度(avgqu-sz)类似于单位时间里平均排队人的个数
- 平均服务时间(svctm)类似于收银员的收款速度
- 平均等待时间(await)类似于平均每人的等待时间
- 平均I/O数据(avgrq-sz)类似于平均每人所买的东西多少
- I/O 操作率 (%util)类似于收款台前有人排队的时间比例
设备IO操作:总IO(io)/s = r/s(读) +w/s(写)
平均等待时间=单个I/O服务器时间*(1+2+...+请求总数-1)/请求总数
每秒发出的I/0请求很多,但是平均队列就4,表示这些请求比较均匀,大部分处理还是比较及时。
iotop
查看io高的进程
3、进程性能分析
通过全局观察,可以看出每个进程占用系统cpu、内存的情况,确定可疑进程后就可以专门进行分析。
pstack
pstack是一个脚本工具,可显示每个进程的栈跟踪。
$pstrack <program-pid>
pstack用来跟踪进程栈,这个命令在排查进程问题时非常有用,比如我们发现一个服务一直处于work状态(如假死状态,好似死循环),使用这个命令就能轻松定位问题所在;可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方。
strace
strace常用来跟踪进程执行时的系统调用和所接收的信号。
strace -o output.txt -T -tt -e trace=all -p 28979
跟踪28979进程的所有系统调用(-e trace=all),并统计系统调用的花费时间,以及开始时间(以可视化的时分秒格式显示),最后将记录结果存在output.txt文件里面。
查看进程正在做什么(实时输出进程执行系统调用的情况):
$strace -p <process-pid>
每一行都是一条系统调用,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。 strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核。
gdb -pg xxx.c编译生成带性能分析的二进制,运行后会生成gmon.out,gdb a.out gmon.out会输出性能分析报告。
perf
Perf是一个包含22种子工具的工具集,以下是最常用的5种:
perf-list:列出支持的热点
perf-stat:分析程序性能 -p
perf-top/perf top -p ,-G得到函数的调用关系图 perf top -s comm,可以查看当前系统运行进程占比
perf-record
perf-report
参考链接:https://blog.csdn.net/zhangskd/article/details/37902159
4、代码优化
优化自己开发的程序,建议采用以下准则:
- 二八法则:在任何一组东西中,最重要的只占其中一小部分,约20%,其余80%的尽管是多数,却是次要的;在优化实践中,我们将精力集中在优化那20%最耗时的代码上,整体性能将有显著的提升;这个很好理解。函数A虽然代码量大,但在一次正常执行流程中,只调用了一次。而另一个函数B代码量比A小很多,但被调用了1000次。显然,我们更应关注B的优化。
- 编完代码,再优化;编码的时候总是考虑最佳性能未必总是好的;在强调最佳性能的编码方式的同时,可能就损失了代码的可读性和开发效率;
参考链接:
https://www.cnblogs.com/zhoug2020/p/6336453.html
https://blog.csdn.net/u011547375/article/details/9851455
https://linuxtools-rst.readthedocs.io/zh_CN/latest/index.html
本文详细介绍如何使用top、sar、vmstat等工具监控系统性能,分析进程行为,并提供代码优化建议。
289

被折叠的 条评论
为什么被折叠?



