Linux下从CPU/内存/IO三个方面来分析系统性能

在实际生产环境中是否遇到如下问题?
系统平均负载过高。
CPU使用率过高。
硬盘利用率已经饱和,IO存在瓶颈。

首先明确一下进程的常见6种状态
R运行状态(running):并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列。
S睡眠状态(sleeping)
D磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
T停止状态(stopped)
Z僵尸状态(Zombies)
X死亡状态(dead)

目录

一.sysstat软件包

二.性能分析常用工具

三.性能问题的常见情况

3.1 查看OS的日志

3.2 查看系统平均负载 

3.3 平均负载与CPU利用率

3.4 系统平均负载高同时CPU使用率也高

3.5 系统平均负载高但CPU使用率不高

3.6 由于CPU上下文切换频繁导致系统平均负载升高

3.7 内存不足引起的OS性能下降

四.安卓系统性能分析总结



一.sysstat软件包

        sysstat软件包是一组包含监测系统性能及效率的工具套件,这些工具用于我们收集系统性能数据。比如CPU使用率、硬盘和网络吞吐数据,这些数据的收集和分析,有利于我们判断系统是否正常运行,是提高系统运行效率、安全运行服务器的得力助手。sysstat软件包一般包含如下工具:
sar
iostat
sa1
sa2
sadf
mpstat
sadc
sysstat

sysstat工具包包含两类工具:
即时查看工具:iostat  mpstat sar
累计统计工具:sar
sar 具有这两种功能。因此,sar 是 sysstat 中的核心工具。sar(System Activity Reporter)是系统活动情况报告的缩写。
这些命令有的是服务,有的是查看结果的命令。也有的是即时服务器CPU,内存以及网络的使用率
比如先要打开sa1 sa2或者sysstat 才能使用sar sadf sadc
还有即时服务器的CPU,内存,网络使用率的命令,比如:mpstat iostat

为了实现sar的累计统计,系统必须周期地记录当时的信息,这是通过调用如下三个工具实现的:
sa1: 收集并存储每天系统动态信息到一个二进制的文件中,用作 sadc 的前端程序
sa2: 收集每天的系统活跃信息写入总结性的报告,用作 sar 的前端程序
sadc: 系统动态数据收集工具,收集的数据被写入一个二进制的文件中,它被用作 sar 工具的后端

工具具体使用可参考:http://www.ctohome.com/FuWuQi/1b/688.html

安装
1.命令行安装
sudo apt install sysstat

Linux下从CPU/内存/IO三个方面来分析系统性能_第1张图片

 2.源码编译安装
1)源码下载
http://perso.wanadoo.fr/sebastien.godard/ 下载最新的版本源码包,比如我下载的是sysstat-5.1.1.tar.gz
2)解包:
ar zxvf sysstat-5.1.1.tar.gz
3)编译安装
cd sysstat-5.1.1
make config
这个命令就是用来配置sysstat安装的,如果不用这个命令,可以直接安装到其默认的/usr/local/lib目录中
make
make install

二.性能分析常用工具

CPU利用率:top,mpstat,sar -w, vmstat
内存利用率:free
IO吞吐率:throughput, iops, iostat -x

三.性能问题的常见情况


3.1 查看OS的日志

比如/var/log/messages里面是否有error,fail,warn等信息

3.2 查看系统平均负载 

        使用uptime查看系统平均负载,从这个命令的load average可以知道系统最近 1 分钟、5 分钟、15 分钟的系统平均负载。系统平均负载指的是处于可运行或不可中断状态的平均进程数,理想状态下,每个逻辑CPU运行一个进程,因此例如当前系统的逻辑CPU数量是12,理想状态load average也应该是12,上图的load average是2左右,则表示有CPU处于空闲状态。

3.3 平均负载与CPU利用率

        由于系统平均负载反映的是处于R状态和D状态的进程数,因此不代表CPU的使用率就是高,这两者没有必然的联系。对于计算密集型任务较多的场景来说,系统平均负载的升高意味着CPU使用率上升。但是对于IO密集型任务较多的场景来说,系统平均负载升高时CPU利用率通常都不高,因为有很多进程都处于D状态。
1) 如果系统平均负载率很高同时CPU的使用率也很高,则需要考虑的是系统可能遇到了CPU瓶颈,需要去定位CPU方面的原因。
2) 如果系统平均负载率很高,但是CPU的使用率不高,则需要考虑的是系统可能遇到了IO瓶颈,需要去定位IO方面的原因。

3.4 系统平均负载高同时CPU使用率也高

       需要去定位CPU方面的原因。
1) 首先使用下面的命令查看每一秒的CPU的核心的变化信息:
mpstat -P ALL 1
2) 使用pidstat命令去查看进程占用的CPU情况:
pidstat -u 1

3.5 系统平均负载高但CPU使用率不高

       需要去定位IO方面的原因。
1) 首先使用下面的命令查看每一秒的CPU的核心的变化信息:
mpstat -P ALL 1
可以看到iowait占用比较高
2) 使用sar -d -p 1查看哪个块设备的使用率比较高。
3) 使用pidstat -d 1命令查看具体是哪个进程导致IO升高的。

3.6 由于CPU上下文切换频繁导致系统平均负载升高

        一般每次上下文切换都需要几十纳秒到数微秒的 CPU 时间,如果切换较多还是很容易导致 CPU 时间的浪费在寄存器、内核栈以及虚拟内存等资源的保存和恢复上,
这里同样会导致系统平均负载升高。
1) 通过下面的命令查看系统上下文切换:
vmstat 1
2)使用pidstat查看具体的进程上下文切换信息,以判断是哪个。
pidstat -u 1 -w -t
说明大部分sysbench进程都在被强制调度,也就是在争抢CPU资源,说明CPU成为了性能瓶颈。

3.7 内存不足引起的OS性能下降

        可以通过下面的方法去排查:
1) 首先查看dmesg日志,查看是否有Out of memory打印,如果有,说明有程序在申请内存时失败,内存不足,这种情况有可能由两种原因引起。一是物理内存不足,二是内存碎片化严重,导致后面的程序申请大片连续内存时无法分配成功。
2) 通过sar -r 1命令去查看当前的内存的使用率,主要看%memused,如果使用率超过了90%,说明物理内存已经不足。
3) 通过sar -W 1命令查看交换分区的活动,如果pswpin/s和pswpout/s的值比较高,说明物理内存已经不足,正常这个值是0。
4) 通过vmstat -a命令中的swpd查看交换分区使用的大小,以此进一步判断物理内存是否已经不足。
5) 通过pidstat -r 1命令查看%MEM域,查看哪些进程占用的内存过多。
 

四.安卓系统性能分析总结

安卓系统也是基于Linux内核的,关于其性能分析常用总结如下:

1)查找进程名称 adb shell ps -ef | grep com.test.xuexi

21332 u0_a290 10 -10 1.6G 345M 189M S 15.3 6.0 2:42.39 com.test.xuexi

21578 u0_a290 20 0 1.1G 100M 82M S 0.6 1.7 0:05.89 com.test.xuexi:remote

2)分析对应进程线程CPU和内存消耗

adb shell top -H | grep u0_a290

3)显示所有线程的CPU和内存消耗

adb shell top -H 

4)查找进程21332下的所有线程CPU和内存消耗

adb shell top -H -p 21332

5) 进入adb shell统计进程信息

adb shell
top | grep com.test.xuexi | grep -v shell

6) top -d -n

-b:查找所有(top默认按照cpu消耗排序且只会展示一屏的信息,-b表示要展示所有的进程信息)
-d:刷新的时间间隔,默认是5秒
-n:指定刷新次数

7) 命令行参数

-d 1 -n 300 -n-long 8000 -device-id 00000000112da443 -package-name com.test.xuexi -launch-activity .NaviAutoActivity -os-version 8.0 -seed 200 -throttle 500 -time 20000 -onlymonkey 0

8)启动weditor来定位安卓界面元素

python -m weditor

9) 枚举设备

adb devices
例如得到:HA1FRPDH

10)top查看指定设备性能信息

adb -s HA1FRPDH shell top

11)dumpsys查看指定设备cpu消耗

adb -s HA1FRPDH dumpsys cpuinfo

12)adb install 常用命令行参数说明

-r :覆盖安装
-l :锁定应用程序
-t :允许测试包
-d :允许降级覆盖安装
-p :部分应用安装
-g :为应用程序授予所有运行时的权限

13)top vs dumpsys使用举例

adb shell dumpsys meminfo com.test.xuexi
adb shell dumpsys cpuinfo | grep com.test.xuexi
adb shell top -b -n 1 | grep com.test.xuexi

14)dumpsys使用

Android程序内存被分为2部分:native和dalvik,dalvik就是我们平常说的java堆,我们创建的对象是在这里面分配的。dumpsys能做的事还有很多
dumpsys [options] 
-meminfo 显示内存信息 
-cpuinfo 显示CPU信息 
-account 显示accounts信息 
-activity 显示所有的activities的信息 
-window 显示键盘,窗口和它们的关系 
-wifi 显示wifi信息

15)VSS,RSS ,PSS ,USS

VSS- Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS- Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS- Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS- Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

16) dumpsys统计app性能参数自动化脚本

#!/bin/bash
starttime=`date "+%Y-%m-%d_%H-%M-%S"`
dirname=testmem_$starttime
mkdir $dirname
cd $dirname
mkdir meminfo
echo "Time,TOTAL,Java,Native,Code,Stack,Graphics,Other,System" > mem.csv 
#exit 0
while true
do
    datetime=`date "+%Y-%m-%d_%H-%M-%S"`
    filename=meminfo/${datetime}.txt
    pid=`adb shell pidof com.test.xuexi`
    adb shell dumpsys meminfo $pid > ${filename}
    Java=`cat ${filename}|grep "Java Heap:"|awk '{print $3}'`
    Native=`cat ${filename}|grep "Native Heap:"|awk '{print $3}'`
    Code=`cat ${filename}|grep "Code:"|awk '{print $2}'`
    Stack=`cat ${filename}|grep "Stack:"|awk '{print $2}'`
    Graphics=`cat ${filename}|grep "Graphics:"|awk '{print $2}'`
    Other=`cat ${filename}|grep "Private Other:"|awk '{print $3}'`
    System=`cat ${filename}|grep "System:"|awk '{print $2}'`
    TOTAL=`cat ${filename}|grep "TOTAL:"|awk '{print $2}'`
    echo "$datetime,$TOTAL,$Java,$Native,$Code,$Stack,$Graphics,$Other,$System"
    echo "$datetime,$TOTAL,$Java,$Native,$Code,$Stack,$Graphics,$Other,$System" >> mem.csv 
    sleep 1
done

17) grep过滤重定向

adb shell top -b -d 1 | grep 30286 --line-buffered > result.txt 

18) 采集1000个点

adb shell top -b -n 1000 -d 1 | grep --line-buffered com.test.xuexi
adb shell top -b -n 1000 -d 1 | grep --line-buffered 22036

你可能感兴趣的:(linux)