◆版權聲明:本文出自胖喵~的博客,轉載必須注明出處。
轉載請注明出處:http://www.cnblogs.com/by-dream/p/5143192.html
前言
第一節講CPU的時候留下了一個疑問,就是由於Android手機系統本身的缺陷造成采集CPU百分比數據會有很大的誤差,那么如何分析CPU這個指標呢?
這節我們就來講講如何用CPU時間片這個指標來衡量系統CPU的占用或者一款App對系統CPU的占用。
概念
首先需要知道,在Linux系統下,CPU利用率分為用戶態、系統態、空閑態,分別表示CPU處於用戶態執行的時間,系統內核執行的時間,和空閑系統進程執行的時間。(如下圖)
CPU使用率計算公式如下:
那么我們來看看怎么這個時間究竟是什么?
先介紹幾個和Linux時間有關的名詞:HZ、tick與jiffies。
HZ:Linux 核心每隔固定周期會發出timer interrupt (IRQ 0),HZ是用來定義每一秒有幾次timer interrupts。例如HZ為1000,就代表每秒有1000次timer interrupts。
這是我在Nexus 5 上截取的手機試試的一個cpu頻率
Tick :Tick是HZ的倒數,Tick = 1/HZ 。即timer interrupt每發生一次中斷的時間。如HZ為250時,tick為4毫秒(millisecond)。
Jiffies :Jiffies 為Linux核心變數,是一個unsigned long類型的變量,它被用來記錄系統自開機以來,已經過了多少tick。每發生一次timer interrupt,Jiffies變數會被加1.
所以我們可以得出,CPU利用率計算公式也就是:
那么如果查看Jiffies 值呢?
Jiffies
查看Jiffies的方法,我需要在shell中輸入cat /proc/stat命令
上圖中的前5行是我們關注的重點,首先縱向CPU0、CPU1、CPU2、CPU3說明當前手機是四核的CPU,代表了每個核的Jiffies ,第一行CPU 就代表總的的Jiffes。
而每一列的數值分別代表了(如上圖所示),詳細的含義如下:
user :從系統啟動開始累計到當前時刻,用戶態的jiffies ,不包含 nice值為負進程;
nice :從系統啟動開始累計到當前時刻,nice值為負的進程所占用的jiffies;
system :從系統啟動開始累計到當前時刻,系統態的jiffies;
idle :從系統啟動開始累計到當前時刻,除硬盤IO等待時間以外其它等待的jiffies;
iowait : 從系統啟動開始累計到當前時刻,硬盤IO等待的jiffies;
irq : 從系統啟動開始累計到當前時刻,硬中斷的jiffies;
softirq :從系統啟動開始累計到當前時刻,軟中斷的jiffies。
總的Jiffies就是上面所有項加起來的總和。因此我們計算一段時間的CPU占用率的時候就可以使用:
total=user+system+nice+idle+iowait+irq+softirq
cpu usage=[(user_end +sys_end+nice_end) - (user_begin + sys_begin+nice_begin)]/(total_end - total_begin)*100
進程的Jiffes
根據上面的介紹我們已經知道了Jiffies的作用,所以當有的時候我們需要查看一個App的CPU性能時,就需要對該App應用的進程的Jiffies進行分析。獲取應用Jiffies的方法這里還是介紹兩種,一種是使用GT直接采集,第二種是命令行查看的方式。
一、GT采集
如同前一節的方法一樣,選擇好要采集的應用(以qq為例),勾選Jiffes,開始采集即可。(如下圖)
一般我們關注的是應用的前台進程,從進程名我們可以區分出來:
使用GT,可以直接查看數據,也可以將源數據保存下來,自己做分析。
二、shell獲取
shell的命令為: cat /proc/進程id/stat
首先我們需要使用 ps 命令查看qq這個應用的前台進程的進程id是多少,然后再去查看它的信息,如下圖:
我們可以看到,得到了很多數據,這些數據的含義分別是:
pid=20324 進程號(平時所說的pid)
comm=(encent.mobileqq) 應用程序或命令的名字
task_state=S 任務的狀態,R:runnign, S:sleeping (TASK_INTERRUPTIBLE), D:disk sleep (TASK_UNINTERRUPTIBLE), T: stopped, T:tracing stop,Z:zombie, X:dead
ppid=174 父進程ID
pgid=174 線程組號
sid=0 c該任務所在的會話組ID
tty_nr=0 (pts/3) 該任務的tty終端的設備號,INT(34817/256)=主設備號,(34817-主設備號)=次設備號
tty_pgrp=-1 終端的進程組號,當前運行在該任務所在終端的前台任務(包括shell 應用程序)的PID。
task->flags=1077936448 進程標志位,查看該任務的特性
min_flt=166543 該任務不需要從硬盤拷數據而發生的缺頁(次缺頁)的次數
cmin_flt=1212 累計的該任務的所有的waited-for進程曾經發生的次缺頁的次數目
maj_flt=454 該任務需要從硬盤拷數據而發生的缺頁(主缺頁)的次數
cmaj_flt=0 累計的該任務的所有的waited-for進程曾經發生的主缺頁的次數目
utime=8582 該任務在用戶態運行的時間,單位為jiffies
stime=3419 該任務在核心態運行的時間,單位為jiffies
cutime=0 累計的該任務的所有的waited-for進程曾經在用戶態運行的時間,單位為jiffies
cstime=7 累計的該任務的所有的waited-for進程曾經在核心態運行的時間,單位為jiffies
priority=20 任務的動態優先級
nice=0 任務的靜態優先級
.......(內容太多,如需了解自己去查閱資料吧,這里只介紹和本節有關的)
根據上面每個字段的含義,我們就可以知道,當前進程的我們要的Jiffies值就是utime和stime的和。