Android性能排查常用命令

前言

android基於Linux,所以android一些常用的命令還是需要掌握的,可以方便我們更好的理解android系統。樓主也經常忘記這些命令的意義,趁這次機會,比較全面的總結一下。

1.ps

首先,第一個是ps命令,這個命令不多說,大家應該都清楚,這裏只強調一個不經常使用的命令。

ps -T  [pid]

這個命令可以打印出當前進程的所有線程。java線程映射在原生的linux系統之上。
下面以我的手機爲例,打印的線程。
在這裏插入圖片描述
從中大家可以看到,PID可以理解爲線程ID,PPID可以理解爲父線程的線程id,與linux的進程的對應關係是一樣的,只是由進程改爲了線程。這裏可以用更專業的tid和ttid來使用
從這個裏面可以看出很多有意思的東西。
首先,10138可以看出是所有線程的父線程,也就是我們的主線程,可以看出和pid相等。類似init進程是所有進程的父進程。
其次,還有以下幾個孃胎裏面帶着的線程

  • JIT,這個不需要解釋吧,java著名的即時編譯(just-in-time)
  • Signal Catcher(ANR等相關處理就在這裏,這個知識點很有意思,大家可以參考Android trace文件抓取原理
    或者gityuan的java層次trace文件和native層trace文件。),
  • JDWP(調試專用),
  • 兩個binder線程池(想想哪兩個,ApplicationThread肯定有一個,還有一個是和WMS交互的)。
  • RenderThread,這個不用解釋吧?android渲染線程,還記得三緩衝嗎?

大家還可以發現,主線程的pid就是進程id,而主線程的父線程的ppid就是645。而645就是android大名鼎鼎的zygote進程。
這裏面的線程,除了blockcannary和leakcannary相關線程,其他每個都涉及很多知識點,我們後面的博客再來討論。

uptime

這個命令使用來看平均負載的。
在這裏插入圖片描述
這個個字段分別是1分鐘,5分鐘,15分鐘的活躍進程數,可見這裏的活躍進程數是慢慢變大的。
簡單說一下這個活躍進程數:單位時間內,系統處於可運行狀態和不可中斷狀態的平均進程數也就是平均活躍進程數,注意,與cpu使用率並沒有關係。
可運行狀態的進程,是指正在使用CPU或者正在等待CPU的進程,也就是我們用ps明亮看到的,處於R狀態進程。
不可中斷進程則是正處於內核態關鍵流程中的進程,並且這些流程是不可打斷的,比如最常見的是等待硬件設備的I/O響應,也就是我們在ps命令中看到的D狀態。
具體可見Linux進程狀態這篇文章
這裏再強調下,與CPU使用率沒有任何關係

  • CPU密集型進程,使用大量CPU會導致平均負載升高,此時兩者是一致的;
  • I/O密集型進程,等待I/O也會導致平均負載升高,但CPU使用率不一定很高。
  • 大量等待CPU的進程調度也會導致平均負載升高,此時CPU使用率也會比較高。
    如果在Linux上,還可以通過iostat,mpstat和pidstat來找出平均負載高的罪魁禍首,但是android不支持,就不多說了。

/proc文件夾下

下面說說/proc文件夾下android可以使用的命令行

schedstat

/proc/[pid]/schedstat

查看 CPU 上下文切換次數。
什麼是CPU上下文切換?什麼是上下文?怎麼切換?大家都知道CPU上下文切換是以線程爲單位的。那麼,上下文切換就包括三種:進程內,進程間,和中斷。這裏設計到Linux底層,暫時不展開,以後再說。
還是以我的華爲手機爲例,看看輸出。
在這裏插入圖片描述
這幾個字段意思可以參考linux調度器(十)——調度器/proc信息解讀

  • 第一個字段是 sum_exec_runtime累計運行的物理時間
  • 第二個字段是 wait_sum累計在就緒隊列裏的等待時間
  • 第三個字段是 nr_switches 主動切換和被動切換的累計次數

status

/proc/[pid]/status

在這裏插入圖片描述
這些字段的含義很清楚,需要重點關注的有

  • Threads:線程數
  • voluntary_ctxt_switches: 0 //主動的切換
  • nonvoluntary_ctxt_switches: 8310 //被動的切換

stat

/proc/[pid]/stat 或者去掉 pid  ,即/proc/stat

這個大概是最蛋疼的命令行了,一堆數字,可讀性很差,可以參考Linux環境下進程的CPU佔用率
linux /proc/stat 文件說明
樓主每次用也是拿着別人的博客對着看,很麻煩,所以用的很少。

有以上信息可以得出 cpu是4核的,cpu這項對應信息如下
cpu     user    nice    system  idle    iowait  irq softirq steal   guest   guest_nice
user:用戶態的CPU時間
nice:低優先級程序所佔用的用戶態的cpu時間。
system:系統態的CPU時間
idle:CPU空閒的時間(不包含IO等待)
iowait:等待IO響應的時間
irq:處理硬件中斷的時間
softirq:處理軟中斷的時間
steal:其他系統所花的時間(個人理解是針對虛擬機)
guest:運行時間爲客戶操作系統下的虛擬CPU控制(個人理解是訪客控制CPU的時間)
guest_nice:低優先級程序所佔用的用戶態的cpu時間。(訪客的)
intr 這行展示系統中斷的信息,第一個爲自系統啓動依賴,發生的所有中斷的次數;然後每個數對應一個特定的中斷自系統啓動以來所發生的次數。
ctxt 這行展示自系統啓動以來CPU發生的上下文交互的次數
btime 這行展示從系統啓動到現在爲止的時間(以UTC時間開始計算,單位爲秒)
processes 這行展示自系統啓動以來所創建的任務的個數
procs_runnig 這行顯示當前運行隊列的任務數目
procs_blocked 這行顯示當前被阻塞的任務數目
spftirq 這行顯示軟中斷的情況

dumpsys

提到android,就不得不提這個命令。這個命令寫全了,可以寫一整個博客,大家可以自己去網上搜索這個命令,這裏就不多說了。這裏說幾個常用的,因爲這個命令實在太強大了

dumpsys cpuinfo

可以看到輸出如下:
在這裏插入圖片描述

dumpsys meminfo

這個命令行輸出的很多,晚點再來詳細講講Linux的虛擬內存。

am

這個是android特有的命令,可以看到,am即ActivityManager的縮寫,也就是能通過ActivityManageService拿到所有消息。具體大家也可以通過搜索去查

pm

上面am命令走的是AMS,那麼pm走的就是PMS,也不多說,大家自己去看。

樓主在接觸命令行之前,一直有個疑惑,就是內存泄漏

比如說,檢測內存泄漏,如果是應用泄漏還好,可以使用leakcannary等內存檢測工具檢測出來,如果是句柄泄漏,socket泄漏,或者io流沒有關閉呢?這個怎麼解決。
以及,最常見的死鎖問題,在java中可以使用jdk的命令行來解決,那麼android裏面怎麼來解決?答案是通過trace文件來解決。
衆所周知,trace文件在發生ANR的時候纔會產生,那麼,有沒有自己去生成trace文件呢?有,就是我們接下來的主角

kill

通過以下命令

adb shell kill -3 [pid]

因爲SIGQUIT等於3,所以直接寫3就可以。
注意,這裏必須是root的機器,才能打開kill權限。或者在代碼裏面直接調用也可以

Process.sendSignal(pid, 3);

這是系統層面暴露給我們的方法。

額外知識點:root權限

另外,額外說一句,其實,linux很多不支持的命令行,或者只有root權限才能使用的命令行,可以通過Magisk刷系統,據說這是一個臺灣的學生開發的,汗顏。
大家可以自己去搜索magisk的相關使用,這個給個參考鏈接每個 Android 玩家都不可錯過的神器(一):Magisk 初識與安裝
個人覺得,堪比之前的Xposed。
比如樓主之前遇到過的一個奇怪問題,即socket始終連接不上服務器,就只能通過root手機來修改socket底層相關原理纔行。
可以參看相關博客tcp_timestamps tcp_tw_recycle引起的服務器連接不上問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章