- 01.CPU概念介绍
- 1.1 思考一下问题
- 1.2 CPU内存架构
- 1.3 CPU读写数据
- 1.4 CPU换成&共享
- 1.5 CPU使用率
- 02.CPU如何收集
- 03.CPU排查分析
- 04.CPU优化实践
- 4.1 使用线程池
- 4.2 减少CPU等待
- 4.3 利用CPU闲置时刻
- 05.CPU监控实践
- CPU的内存架构
- image
- 现在的计算机,基本都是多个CPU,并且有些CPU还是多核的,因此你的Java程序中,每个CUP执行一个线程。
- 并且俩个或者俩个以上的CPU在同时执行任务,这种情况就是我么所说的:并发。
- 在Linux系统下CPU分为:
- CPU利用率分为用户态、系统态、空闲态,分别表示CPU处于用户态执行的时间,系统内核执行的时间,和空闲系统进程执行的时间。
- 平时所说的CPU利用率是指:CPU执行非系统空闲进程的时间 / CPU总的执行时间。
- 先介绍几个和Linux时间有关的名词:HZ、tick与jiffies。
- HZ:Linux 核心每隔固定周期会发出timer interrupt (IRQ 0),HZ是用来定义每一秒有几次timer interrupts。例如HZ为1000,就代表每秒有1000次timer interrupts。
- Tick :Tick是HZ的倒数,Tick = 1/HZ 。即timer interrupt每发生一次中断的时间。如HZ为250时,tick为4毫秒(millisecond)。
- Jiffies :在Linux的内核中,有一个全局变量:Jiffies。 Jiffies代表时间。它的单位随硬件平台的不同而不同。jiffies的单位就是 1/HZ。Intel平台jiffies的单位是1/100秒,这就是系统所能分辨的最小时间间隔了。每个CPU时间片,Jiffies都要加1。 CPU的利用率就是用执行用户态+系统态的Jiffies除以总的Jifffies来表示。
- CPU利用率计算公式也就是:
- CPU使用率=(用户态Jiffies+系统态Jiffies)/总Jiffies
- CPU是系统非常重要的资源,在Android中/proc/stat
- 包含了所有CPU的相关详情信息,查看CPU使用情况,CPU不是一个瞬时态,而是一个过程态的体现,一般可以使用top命令和dump cpuinfo命令进行CPU占用率获取。
- top命令获取方法
- top是比较经典的CPU计算方法,总的cpu时间 = user + nice + system + idle + iowait + irq + softirq
- 例如:User 147 + Nice 11 + Sys 79 + Idle 408 + IOW 1 + IRQ 0 + SIRQ 6 = 652
- 而proc->delta_time是两次读取/proc/pid/stat相减得到,可见,top是一段时间内,计算process的cpu jiffies与总的cpu jiffies差值得到。
- 通过adb获取top:adb shell top -m 100 -n 1 -s cpu | grep 包名
- dump cpuinfo命令获取方法
- Android特有的命令,dump cpuinfo命令的实现在androidm/frameworks/base/core/java/com/android/internal/os/ProcessCpuTracker.java类里面,方法是printCurrentState
- 进程的总Cpu时间processCpuTime = utime + stime + cutime + cstime,该值包括其所有线程的cpu时间。
- 通过adb获取dump:adb shell dumpsys cpuinfo |grep 包名
- https://www.jianshu.com/p/31b1a4aef550
- 在Android低版本设备中,可以通过读取 /proc/stat 文件实现
- /proc/stat 内容首行有8个数值,分别提供了所有CPU在 用户态(user)、用户态-低优先级(nice)、内核态(sys)、空闲态(idle)、io等待(iowait)、硬中断(irq)、软中断(softirq) 状态 下的时间总和,将这些值累加作为系统总的CPU时间(cpuTime)。
- 计算 iowait/cpuTime 为系统的CPU空闲率,1-cpu空闲率 及为cpu利用率 。注意这里的时间单位为 jiffies,通常一个jiffies 等于10ms。
- 总的cpu时间totalCpuTime = user + nice + system + idle + iowait + irq + softirq + stealstolen +guest
- 在Android 8.0以上版本
- 为了防止旁路攻击,普通应用程序已经无法访问/proc/stat 文件,所以无法通过/proc/stat 的方式计算系统cpu利用率。
- 部分线下性能监控相关的开源库 如Dokit 会在Android8.0以上的设备 通过执行shell 命令 top -n 1 来直接获取某个进程CPU使用率信息,不过这种方式在高版本设备上也是无法使用的,得到的CPU使用率总是为0。
- 计算cpu使用率
- 1、采样两个足够短的时间间隔的Cpu快照,分别记作t1,t2,其中t1、t2的结构均为: (user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;
- 2、计算总的Cpu时间片totalCpuTime。a) 把第一次的所有cpu使用情况求和,得到s1;b) 把第二次的所有cpu使用情况求和,得到s2;c) s2 - s1得到这个时间间隔内的所有时间片,即totalCpuTime = s2 - s1 ;
- 3、计算空闲时间idle。idle对应第四列的数据,用第二次的idle - 第一次的idle即可 idle = idle2 - idle1
- 4、计算cpu使用率。CPU总使用率(%) = 100*((totalCputime2- totalCputime1)-(idle2-idle1))/(totalCputime2-totalCputime1)
- 单个应用CPU监控
- 将选中应用的PID传入,读取/proc/PID/stat文件信息及可获取该PID对应程序的CPU信息。
- 计算方法
- 1、首先获取应用的进程id: adb shell ps | grep com.package | awk '{print $2}' > tmp
- 2、根据进程id,通过proc获取CPU信息 while read line; do adb shell cat /proc/line/stat | awk '{print 14,15,16,$17}' >> appcpu0; done < tmp
- 以下只解释对我们计算Cpu使用率有用相关参数(14-17列) 参数解释
- utime 该任务在用户态运行的时间,单位为jiffies
- stime 该任务在核心态运行的时间,单位为jiffies
- cutime 所有已死线程在用户态运行的时间,单位为jiffies
- cstime 所有已死在核心态运行的时间,单位为jiffies
- 进程的总Cpu时间
- processCpuTime = utime + stime + cutime + cstime,该值包括其所有线程的cpu时间。
- App的CPU占用率
- 之后可以每1s获取一次CPU信息,分析获得app的CPU占用率等信息。
- 单个程序的CPU使用率(%) = 100*(processCpuTime2-processCpuTime1)/(totalCpuTime2-totalCpuTime1)
- 对于线上系统突然产生的运行缓慢问题
- 如果该问题导致线上系统不可用,那么首先需要做的就是,导出 jstack 和内存信息,然后重启系统,尽快保证系统的可用性。
- 这种情况可能的原因主要有两种:
- 代码中某个位置读取数据量较大,导致系统内存耗尽,从而导致 Full GC 次数过多,系统缓慢。
- 代码中有比较耗 CPU 的操作,导致 CPU 过高,系统运行缓慢。
- 另外有几种情况也会导致某个功能运行缓慢,但是不至于导致系统不可用:
- 代码某个位置有阻塞性的操作,导致该功能调用整体比较耗时,但出现是比较随机的。
- 某个线程由于某种原因而进入 WAITING 状态,此时该功能整体不可用,但是无法复现。
- 由于锁使用不当,导致多个线程进入死锁状态,从而导致系统整体比较缓慢。
- https://mp.weixin.qq.com/s/kM_azX-4tND0qydYelB3yg
- https://mp.weixin.qq.com/s/ixm14buRWvsNlV5WpVZCmQ
- https://juejin.cn/post/7253062314307223611
- https://juejin.cn/post/7253062314307223611
- 速度优化:CPU 优化(上)
- https://juejin.cn/post/7253062314307223611#heading-5
- https://juejin.cn/post/7256406423817601085
- Android发热监控实践
- https://blog.itpub.net/70027824/viewspace-2990628/
- 速度优化:充分利用 CPU 闲置时刻
- https://juejin.cn/post/7374616167761444890
- 【车载性能优化】将线程&进程运行在期望的CPU核心上
- https://juejin.cn/post/7258251967956598839
- Android平台下的cpu利用率优化实现
- https://juejin.cn/post/7243240618788388922