就这一次看懂TraceView
一、TraceView的用處
TraceView用于分析計(jì)算性能,流入某個(gè)方法過(guò)于耗時(shí)導(dǎo)致UI卡頓,或者某個(gè)方法調(diào)用次數(shù)過(guò)多,或者某個(gè)方法雖然并不占用太多內(nèi)存但是占用了大量的CPU資源等等。二、獲取TraceView文件的三種方式
1:方式一:通過(guò)代碼獲取
case R.id.bt_trace_view:Debug.startMethodTracing("custom"); startTrace(); Debug.stopMethodTracing(); Utils.showToast(this, "成功"); break;a:在你想要檢測(cè)的某段代碼的開(kāi)始位置調(diào)用Debug.startMethodTracing("custom");
其中custom可根據(jù)需要自定義,其實(shí)就是生成的TraceView文件的文件名,例如custom.trace
b:在你想要檢測(cè)的某段代碼的結(jié)束位置調(diào)用
Debug.stopMethodTracing();
結(jié)束檢測(cè)沒(méi)有參數(shù)。
注意:這兩行代碼要在同一個(gè)線程成對(duì)出現(xiàn)。
c:通過(guò)以上設(shè)置運(yùn)行代碼后就會(huì)在手機(jī)里生成/sdcard/custom.trace文件
d:然后通過(guò)adb pull /sdcard/custom.trace D:\folder命令將custom.trace導(dǎo)出到指定目錄。
2:方式二:通過(guò)Android Studio的Monitor的CPU模塊生成
a:保持app在運(yùn)行狀態(tài),在你要開(kāi)始檢測(cè)某個(gè)功能時(shí)點(diǎn)擊一下按鈕Start Method Tracing;
b:根據(jù)需要操作一下app,再點(diǎn)擊該按鈕Stop Method Tracing,則檢測(cè)區(qū)間結(jié)束,Studio會(huì)打開(kāi).trace文件的查看窗口,這個(gè).trace文件在你app項(xiàng)目的captures目錄下。
c:這個(gè)窗口界面并不友好,也不好用,我們不直接觀察這個(gè)界面,所以我們像方式一一樣將這個(gè).trace文件保存到某個(gè)目錄。
這里為了和上面的方式一統(tǒng)一,我也把這個(gè)文件保存到D:\folder,并且重命名為custom.trace文件。
后面會(huì)著重講打開(kāi).trace文件且分析.trace文件的方法。
3:通過(guò)Tools --> Android --> Android Device Monitor獲取
a:通過(guò)Tools --> Android --> Android Device Monitor路徑進(jìn)入,然后參考下圖開(kāi)始分析;
b:操作一會(huì)app后參考下圖結(jié)束分析你剛才的操作執(zhí)行的代碼;
不采用這種方式產(chǎn)生的.trace文件。
到此,三種獲取.trace文件的方式講完了,第一種方式和第二種方式我們都獲取到了.trace文件,第三種方式我一般不采用。
三:分析trace文件
前面講到的方式一方式二我們獲取到了.trace,下面講解如果打開(kāi)并分析該.trace文件要打開(kāi).trace文件就用到了sdk目錄下的D:\sdk\tools\traceview.bat工具,通過(guò)如下命令就打開(kāi).trace文件并進(jìn)入分析界面
由于通常我們的業(yè)務(wù)代碼比較復(fù)雜,產(chǎn)生的.trace文件也很復(fù)雜不方便我們學(xué)習(xí),所以這里我自己寫(xiě)一段非常簡(jiǎn)單的代碼并通過(guò)前面方式一講到的通過(guò)代碼的方式獲取.trace文件來(lái)講解。
private void test() {Debug.startMethodTracing("custom"); startTrace(); Debug.stopMethodTracing(); Utils.showToast(this, "成功"); }/** * jie1()和jie2()沒(méi)有調(diào)用關(guān)系是兄弟關(guān)系 */ private void startTrace() {jie1(); jie2(); }/** * jie2()中兩次調(diào)用jie3(),其中jie3(0)直接return,不產(chǎn)生遞歸也不會(huì)調(diào)用jie4() * jie3(3)會(huì)先調(diào)用一次jie4()再產(chǎn)生3次遞歸調(diào)用 */ private void jie2() {jie3(0); jie3(3); }private void jie3(int count) {if (count == 3) {jie4(); }if (count == 0) {return; } else {jie3(count - 1); } }/** * 故意做比較耗時(shí)的操作:用于區(qū)分Excl和Incl的關(guān)系 */ private void jie4() {for (int i = 0; i < 15; i++) {for (int j = 0; j < 15; j++) {int k = i + j; }} }private void jie1() {}這段代碼對(duì)應(yīng)的.trace文件如下圖
其中各個(gè)字段的說(shuō)明:
Incl Cpu Time%Incl Cpu Time
某函數(shù)占用的CPU時(shí)間,包含內(nèi)部調(diào)用其它函數(shù)的CPU時(shí)間
Excl Cpu Time%?
Excl Cpu Time
某函數(shù)占用的CPU時(shí)間,但不含內(nèi)部調(diào)用其它函數(shù)所占用的CPU時(shí)間
結(jié)論:父方法的Incl Cpu Time = 父方法的Excl Cpu Time + 子方法的Incl Cpu Time.... ?省略號(hào)說(shuō)明一個(gè)方法可以調(diào)用多個(gè)方法
Incl Real Time%
Incl Real Time
某函數(shù)運(yùn)行的真實(shí)時(shí)間(以毫秒為單位),內(nèi)含調(diào)用其它函數(shù)所占用的真實(shí)時(shí)間
Excl Real Time%
Excl Real Time
某函數(shù)運(yùn)行的真實(shí)時(shí)間(以毫秒為單位),不含調(diào)用其它函數(shù)所占用的真實(shí)時(shí)間
結(jié)論:父方法的Incl Real Time = 父方法的Excl Real Time + 子方法的Incl Real Time....省略號(hào)說(shuō)明一個(gè)方法可以調(diào)用多個(gè)方法
Call+Recur Calls/Total
沒(méi)展開(kāi)某個(gè)方法時(shí):
會(huì)顯示該方法被程序員主動(dòng)調(diào)用次數(shù),以及被自身遞歸調(diào)用次數(shù);例如:2+3,程序員調(diào)用兩次,自己遞歸調(diào)用3次
展開(kāi)某個(gè)方法時(shí):
父方法會(huì)顯示:其調(diào)用(程序員主動(dòng)調(diào)用,非遞歸)該方法的次數(shù)/該方法的總次數(shù),例如:2/5,說(shuō)明該方法總共被調(diào)用5次其中父方法主動(dòng)調(diào)了他2次
子方法會(huì)顯示:子方法被其調(diào)用(程序員主動(dòng)調(diào)用)的次數(shù)/子方法被調(diào)用的總次數(shù),例如1/5
注意:這里的程序員主動(dòng)調(diào)用是指,你看到的代碼調(diào)用了幾次就是幾次,并不包括代碼運(yùn)行中的遞歸
例如funcA(){
funcD();
funcB();
funcB();
}
這里程序員主動(dòng)調(diào)用了兩次funcB()一次funcD(),并沒(méi)有管funcB()有沒(méi)有遞歸的情況。
再例如funcB(){
funcB();
funcB();
}
這里funcB()產(chǎn)生了遞歸,但是程序員在funcB()中只主動(dòng)調(diào)用了2次funcB();不管funcB()遞歸了多少次。
Cpu Time/Call
某函數(shù)的Incl Cpu Time與調(diào)用次數(shù)的比。相當(dāng)于該函數(shù)平均執(zhí)行時(shí)間,注意不是Excl Cpu Time;
Real Time/Call
某函數(shù)的Incl Real Time與調(diào)用次數(shù)的比。相當(dāng)于該函數(shù)平均執(zhí)行時(shí)間,注意不是Excl Real Time;
注意:這些列可以左右拖動(dòng)調(diào)換位置
通過(guò)對(duì)TraceView文件的分析,如果發(fā)現(xiàn)某個(gè)方法運(yùn)行時(shí)間明顯過(guò)長(zhǎng)或者調(diào)用次數(shù)異常過(guò)多,則就存在優(yōu)化的可能
總結(jié)
以上是生活随笔為你收集整理的就这一次看懂TraceView的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 第四届“传智杯”全国大学生IT技能大赛(
- 下一篇: Java中生成随机数的4种方式!