本文共 7017 字,大约阅读时间需要 23 分钟。
【Android Linux内存及性能优化】八 系统性能分析工具
本文接着
《》 《》 《》 《》 《》 《》 《》二、系统性能分析
2.1 性能分析
程序性能的问题,有很多原因,需要对症下药。
导致软件性能低下,主要有下面3种原因:-
程序的运算量很大,导致CPU 过于繁忙,CPU 是瓶颈。
可以运行 top 命令,如果某个进程的CUP 利用率很高,则说明CPU 是性能瓶颈。 -
程序需要大量的I/O ,读写文件、内存操作等,CPU 更多的是处于等待,I/O 部分成为程序性能瓶颈。
对于大量I/O 引起的程序性能问题,可以学习这篇文章: 《》 -
程序之间相互等待,结果CPU 利用率很低,但运行速度依然很慢,程序间的共享与死锁制约了程序的性能。
如果系统的CPU 利用率并不高,而且也不存在大量的I/O 操作,那么很有可能是多个线程之间相互等待造成的,这时就需要对程序进行大规模的重构。
2.1.1 /proc 目录
通过proc 目录,能够了解到CPU 和I/O 设备的工作状况,从而能够帮助分析导致程序性能低下的原因。
2.1.1.1 系统相关 cat /proc/stat
ciellee@sh:~$ cat /proc/stat 累计时间 user nice system idle iowait irq softirqcpu 3167348 29348 1381731 80468196 1075970 0 101955 0 0 0cpu0 397571 3476 157335 10150112 70357 0 35871 0 0 0cpu1 372224 3435 174119 10136025 51305 0 16722 0 0 0cpu2 418781 3775 195023 10131454 32896 0 7197 0 0 0cpu3 381767 4442 166107 10172208 33756 0 14511 0 0 0cpu4 376322 3423 160088 10192147 30325 0 3210 0 0 0cpu5 388663 3460 158360 10202394 29673 0 4082 0 0 0cpu6 435006 3761 212003 9410045 713497 0 5559 0 0 0cpu7 397011 3573 158693 10073807 114157 0 14800 0 0 0intr 185329212 9 479 0 0 0 0 0 0 1 5007429 0 0 0 0 0 0 0 60384 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1954ctxt 550116756btime 1590973874processes 536879procs_running 1procs_blocked 0softirq 198450776 16075871 60900311 42960 3505868 1818711 0 1749208 63006387 0 51351460
CPU 后面数值分别代表着CPU 在不同状态下所用的时间,其单位为 jiffy (0.01s),7个数值的含义分别是:
- user :从系统启动开始累计到当前的时间,用户态的CPU 时间,不包含 nice 值为负的进程。
- nice :从系统启动开始累计到当前时刻,nice 值为负的进程所占用的CPU 时间。
- system :从系统启动开始累计到当前时刻,内核所占用的CPU 时间
- idle :从系统启动开始累计到当前时刻,除硬盘 IO 等待时间以外其他等待时间。
- iowait :比系统启动开始累计到当前时刻,硬盘IO 等待时间。
- irq :从系统启动开始累计到当前时刻,硬中断时间。
- softirq :从系统启动开始累计到当前时刻,软中断时间。
由此可以推导出:
CPU 时间 = user + nice + idle + iowait + irq + softirq
CPU 的利用率 = 1 - (idle)/(user + system + nice + iowait + irq + softirq)
根据CPU 的利用率,可以知道当前系统的CPU 负载情况。
从这些数据,可以知道分析性能瓶颈在哪里:
-
程序代码有问题,导致占用了大量的CPU ,可以计算CPU 用户态利用率
CPU 用户态利用率 = (user + nice)/(user + system + nice + idle + iowait + irq + softirq)
-
程序代码调用了大量的系统调用,导致Linux 内核占用了大量的CPU
CPU 内核态利用率 = (system)/(user + system + nice + idle + iowait + irq + softirq)
-
系统和Flash 、内存等 有大量的交互和等待,从而导致系统性能下降
IO 利用率 = (iowait)/(user + system + nice + idle + iowait + irq + softirq)
2.1.1.2 系统相关 cat /proc/loadavg
ciellee@sh:~$ cat /proc/loadavg1.97 2.14 1.74 2/1048 6774上面数字中:1.97 : 1分钟平均负载2.14 : 5分钟平均负载1.74 : 15分钟平均负载2 : 在采样时刻,运行队列的任务的数量,与/proc/stat 的procs_running 表示相同意思1048 : 在采样时刻,系统中活跃的任务的个数(不包括运行已经结束的任务)6774 : 最大的 PID 值,包括轻量级进程,即线程
2.1.1.3 进程相关 cat /proc/51/stat
ciellee@sh:~$ cat /proc/51/stat51 (migration/7) S 2 0 0 0 -1 69238848 0 0 0 0 0 11 0 0 -100 0 1 0 4 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 0 0 0 17 7 99 1 0 0 0 0 0 0 0 0 0 0 0每个参数解析如下;pid = 50 进程(线程)pid号comm = migration 应用程序或命名的名字task_state=S 任务的状态:R:running,S:sleeping,D:disk sleep, T:stopped,T:tracing stop,Z:zombie,X:deadppid = 2 父进程IDpgid = 0 线程组号sid = 0 该任务所在的会话组IDttnr = 0 该任务的tty终端的设备号,tty_pgrp = -1 终端的进程组号,当前运行在该任务所在终端的前台任务(包括 shell 应用程序)的pidtask->flags = 69238848 进程标志位,查看该任务的特性min_flt = 0 该任务不需要从硬盘拷数据而发生的缺页(次缺页)次数cmin_flt = 0 累计的该任务的所有的waited-for 进程曾经发生的次缺页的数目maj_flt = 0 该任务需要从硬盘拷数据而发生的缺页(主缺页)次数cmaj_flt = 0 累计的该任务的所有的waited-for 进程曾经发生的主缺页的数目utime = 0 该任务在用户态运行的时间,单位为 jiffystime = 11 该任务在核心态运行的时间,单位为 jiffycutime = 0 累计的该任务的所有的waited-for 进程曾经在用户态运行的时间,单位为 jiffycstime = 0 累计的该任务的所有的waited-for 进程曾经在核心态运行的时间,单位为 jiffypriority = -100 任务的动态优先级nice = 0 任务的静态优先级num_threads = 1 该任务所在的线程组里线程的个数it_real_value = 0 由于计时间隔导致下一个SIGALRM 发送进程的时延,以jiffy 为单位start_time = 4 该任务的启动的时间,单位为 jiffyvsize = 0 该任务的虚拟地址空间大小rss = 0(page) 该任务当前驻留虚拟地址空间的大小vsize = 18446744073709551615(bytes) 该任务的虚拟空间大小rss = 0(page) 该任务当前驻留物理地址空间的大小rlim = 0(bytes) 该任务能驻留物理地址空间的最大值start_code = 0 该任务在虚拟地址空间的代码段的起始地址end_code = 0 该任务在虚拟地址空间的代码段的结束地址start_stack = 0 该任务在虚拟地址空间的栈的结束地址kstkesp = 0 esp(32位堆栈指针)的当前值,与在进程的内核堆栈页得到的一致 kstkeip = 0 指向将要执行的指令的指针,EIP(32位指令指针)的当前值pendingsig = 2147483647 待处理信号的位图,记录发产送给进程的普通信号block_sig = 0 阻塞信号的位图sigign = 0 忽略的信号的位图sigcatch = 0 被俘获的信号的位图wchan = 0 如果该进程是睡眠状态,该值给出调度的调用点nswap = 17 被 swapped 的页数,当前没用cnswap = 7 所有子进程被swapped 的页数和,当前没用exit_signal = 99 该进程结束时,向父进程所发送的信号task_cpu(task) = 1 运行在哪个CPU 上task_rt_priority = 0 实时进程的相对优先级别task_policy = 0 进程的调度策略,0:非实时进程,1:FIFO实时进程,2:RR实时进程
通过文件stat 的utime, stime, cutime 和 cstime 的数值,能够计算出进程的CPU 占用率。
要想获得CPU 占用率,需要两个采样点:
采样点1: 系统时间记为 sys1, 进程时间分别为:utime1,stime1,cutime1,cstime1 采样点2: 系统时间记为 sys2, 进程时间分别为:utime2,stime2,cutime2,cstime2进程CPU 占用率 = ( (utime2 + stime2 - cutime2 - stime2) - (utime1 + stime1 - cutime1 - stime1) ) / (sys2 - sys1)
进程用户态占用率 = ( (utime2 - cutime2) - (utime1 - cutime1) ) / (sys2 - sys1)
进程内核态占用率 = ( (stime2 - stime2) - (stime1 - stime1) ) / (sys2 - sys1)
2.1.1.4 进程相关 top
top 是最常用来监控系统范围内进程活动的工具,它提供运行在系统上的与CPU 关系最密切的进程列表,以及许多有意义的统计值(如负载平均,进程数量 以及 使用的 存储器和页面空间的数量)。
Tasks: 302 total, 1 running, 229 sleeping, 0 stopped, 0 zombie%Cpu(s): 3.7 us, 1.6 sy, 0.0 ni, 93.2 id, 1.3 wa, 0.0 hi, 0.1 si, 0.0 stKiB Mem : 16281312 total, 2675480 free, 2865172 used, 10740660 buff/cacheKiB Swap: 16605180 total, 16598768 free, 6412 used. 12037752 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3571 ciellee 20 0 2139236 191748 40460 S 23.5 1.2 96:04.80 compiz 1141 root 20 0 580232 185248 137744 S 17.6 1.1 41:17.93 Xorg 3315 ciellee 20 0 827724 302988 15876 S 11.8 1.9 1:40.13 hud-service 3515 ciellee 20 0 2036500 104556 49964 S 11.8 0.6 1:17.75 nautilus 2521 ciellee 20 0 2951112 209128 36744 S 5.9 1.3 112:49.49 WeChat.exe 3270 ciellee 20 0 516464 48528 18988 S 5.9 0.3 0:23.38 bamfdaemon 3341 ciellee 20 0 704340 120900 24328 S 5.9 0.7 7:01.88 unity-panel-ser 24020 ciellee 20 0 24928 4140 3404 R 5.9 0.0 0:00.03 top 1 root 20 0 175892 5764 3220 S 0.0 0.0 0:03.46 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.13 kthreadd 4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H 6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq
转载地址:https://ciellee.blog.csdn.net/article/details/106495793 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!