成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Android性能優(yōu)化

dongxiawu / 2682人閱讀

摘要:相對(duì)的在性能優(yōu)化方面,相當(dāng)于將的功能集成到了中。手機(jī)連接電腦后運(yùn)行應(yīng)用,在中會(huì)看到以下視圖左上角可以選擇設(shè)備和進(jìn)程,點(diǎn)擊區(qū)域,即可進(jìn)入視圖左上角可以選擇跟蹤模式按默認(rèn)采樣率捕獲應(yīng)用的調(diào)用堆棧。

前言

性能優(yōu)化的過(guò)程分兩部分:

發(fā)現(xiàn)性能瓶頸

制定方案,解決性能問(wèn)題

解決性能問(wèn)題的方案需要具體情況具體分析,并沒(méi)有完全固定的路子,更多的是靠經(jīng)驗(yàn)的積累,本文不做涉及。但是發(fā)現(xiàn)性能瓶頸確實(shí)有著固定的方法。本文主要介紹 如何找到性能瓶頸 。

如何找到性能瓶頸

常用的性能檢測(cè)工具是traceview,集成于 Android Device Monitor 中。從Android Studio3.0開(kāi)始, Android Device Monitor 被廢棄,取而代之的是 Android Profiler ,其中提供了 Memory Prodiler 、CPU Profiler、Network Prodiler三大功能。

內(nèi)存優(yōu)化(包括內(nèi)存泄漏)常用的是 MAT 或者 LeakCanary ,而 Memory Profiler 相當(dāng)于將 MAT 的簡(jiǎn)化版功能集成到 AS 中。相對(duì)的在性能優(yōu)化方面,CPU Profiler 相當(dāng)于將 traceview 的功能集成到了 AS 中。

所以,使用AS3.0之前版本的,可以使用traceview,而使用AS3.0以后版本的,除了traceview,還可以選擇CPU Profiler。

如果想追蹤系統(tǒng)進(jìn)程的詳細(xì)數(shù)據(jù),以解決幀引起的界面卡頓等問(wèn)題,可以使用 systrace ,本文不做涉及。

traceview 使用方法

使用 traceview 需要首先使用 Debug 類進(jìn)行 插樁 ,當(dāng)應(yīng)用執(zhí)行到被插樁的代碼時(shí)就會(huì)在手機(jī)sdcard中自動(dòng)生成 .trace 文件,之后使用 traceview 或者 AS(3.0以上版本)打開(kāi)文件即可。

一、插樁

插樁需要使用到 Debug 類,并且會(huì)在 sdcard 中生成 .trace 文件,所以你必須首先保證你的應(yīng)用具有寫(xiě)外部存儲(chǔ)( WRITE_EXTERNAL_STORAGE )的權(quán)限。

在想要跟蹤的代碼邏輯開(kāi)頭和結(jié)尾處分別插樁:

// Starts recording a trace log with the name you provide. For example, the

// following code tells the system to start recording a .trace file to the

// device with the name "sample.trace".

Debug.startMethodTracing("sample");

...

// The system begins buffering the generated trace data, until your

// application calls stopMethodTracing(), at which time it writes

// the buffered data to the output file.

Debug.stopMethodTracing();

生成的 .trace 文件會(huì)被保存在固定目錄下,與 getExternalFilesDir() 返回的目錄相同,即 /sdcard/Android/data/[YOUR_PACKAGE_NAME]/files 下。

請(qǐng)注意,如果您的應(yīng)用在未更改跟蹤日志名稱的情況下再次調(diào)用 startMethodTracing(),則會(huì)覆蓋已保存至設(shè)備的現(xiàn)有日志。如果希望每次運(yùn)行都保存至不同的日志文件,可以使用如下代碼:

// Uses the SimpleDateFormat class to create a String with

// the current date and time.

SimpleDateFormat date =

new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss");

String logDate = date.format(new Date());

// Applies the date and time to the name of the trace log.

Debug.startMethodTracing(

"sample-" + logDate);

如果系統(tǒng)在您調(diào)用 stopMethodTracing() 之前達(dá)到最大緩沖值,則會(huì)停止跟蹤并向管理中心發(fā)送通知。 開(kāi)始和停止跟蹤的函數(shù)在您的整個(gè)應(yīng)用流程內(nèi)均有效。 也就是說(shuō),您可以在 Activity 的 onCreate(Bundle)

函數(shù)中調(diào)用 startMethodTracing(),在 Activity 的 onDestroy() 函數(shù)中調(diào)用 stopMethodTracing()。

二、查看 .trace 文件

插好樁后,安裝應(yīng)用并運(yùn)行被檢測(cè)部分的功能,然后就可以通過(guò) AS 或者 traceview 查看文件了。

使用 AS 查看

在AS中點(diǎn)擊 View - Tool Windows - Android File Explorer 打開(kāi) Android File Explorer :

在 /sdcard/Android/data/[YOUR_PACKAGE_NAME]/files 下即可找到生成的 .trace 文件,雙擊文件即可打開(kāi)。

將 .trace 文件保存至電腦,直接拖入AS窗口,也可直接打開(kāi)該視圖。

在打開(kāi)的視圖中,左上方可以選擇想要查看的線程??梢圆榭幢O(jiān)控期間指定線程運(yùn)行了多久、執(zhí)行了哪些方法、每個(gè)方法執(zhí)行了多久等等。

其中有4個(gè)名詞需要解釋一下:

Wall Clock Time:壁鐘時(shí)間,表示實(shí)際經(jīng)過(guò)的時(shí)間,即進(jìn)入某個(gè)方法到退出該方法的時(shí)間,不考慮線程是活動(dòng)還是休眠狀態(tài)。

Thread time:線程時(shí)間,表示實(shí)際經(jīng)過(guò)的時(shí)間減去線程沒(méi)有消耗 CPU 資源(處于休眠)的時(shí)間部分。 對(duì)于任何給定函數(shù),其線程時(shí)間始終少于或等于其壁鐘時(shí)間。 使用線程時(shí)間可以讓您更好地了解線程的實(shí)際 CPU 使用率中有多少是給定函數(shù)消耗的。

Inclusive Time:方法執(zhí)行自己代碼的時(shí)間 + 執(zhí)行自己child方法的時(shí)間。

Exclusive Time:方法執(zhí)行自己代碼的時(shí)間。

使用 traceview 查看

要使用 traceview 查看,需要首先將 .trace 文件保存到電腦:

adb pull /sdcard/Android/data/[YOUR_PACKAGE_NAME]/files/sample.trace D:Documentssample.trace

打開(kāi) Android Device Monitor 。AS3.0以前的版本,就是LogCat所在的窗口,再切換一下tab頁(yè)即可。AS3.0以后,進(jìn)入 android-sdk/tools/ 路徑,運(yùn)行以下命令:

monitor

雖然 Android Device Monitor 的 DDMS 也有 File Explorer ,但是未 root 的手機(jī),查看不到上述路徑,因此只能將 .trace 文件保存到電腦查看。

在 Android Device Monitor 中,依次點(diǎn)擊 File - Open File ,選擇 .trace 文件路徑即可打開(kāi):

內(nèi)容與AS打開(kāi)時(shí)類似,相差較大的主要是圖標(biāo)部分,沒(méi)有AS的 Call Chart 直觀形象。

其中也有4個(gè)概念:

Cpu Time:相當(dāng)于AS中的 Thread time。

Real Time:相當(dāng)于AS中的Wall Clock Time。

Inclusive Time:同AS一樣。

Exclusive Time:同AS一樣。

使用 AS 查看還是使用 traceview 查看

這個(gè)就見(jiàn)仁見(jiàn)智了,根據(jù)我個(gè)人使用的感覺(jué)來(lái)看,建議使用AS查看。原因有二:

AS更簡(jiǎn)單。不需要多帶帶打開(kāi)ADM,更不需要將 .trace 文件保存到電腦。

AS的調(diào)用圖( Call Chart )更加直觀,cpu時(shí)間的消耗一目了然。

Call Chart 的水平軸表示函數(shù)調(diào)用(或調(diào)用方)的時(shí)間段和時(shí)間,并沿垂直軸顯示其被調(diào)用者。 下圖展示了一個(gè)調(diào)用圖表示例,并描繪了給定函數(shù)的 self time、children time 以及總時(shí)間的概念。

最后需要注意一點(diǎn),跟蹤分析過(guò)程中,應(yīng)用的運(yùn)行速度會(huì)減慢。所以,通過(guò) traceview 得到的分析數(shù)據(jù)并不能精確反應(yīng)某個(gè)方法在實(shí)際執(zhí)行時(shí)的絕對(duì)時(shí)間。關(guān)于這一點(diǎn),在最后的注意事項(xiàng)中再做詳細(xì)分析。

Google還提供了基于樣本的分析方式,以減少分析對(duì)運(yùn)行時(shí)性能的影響。要啟用樣本分析,需調(diào)用 Debug.startMethodTracingSampling() 方法(而非 Debug.startMethodTracing() 方法)。系統(tǒng)會(huì)定期收集樣本,直至調(diào)用 stopMethodTracing() 。

CPU Profiler 使用方法

使用 CPU Profiler 進(jìn)行函數(shù)跟蹤比 traceview 更簡(jiǎn)單。不需要做任何代碼上的植入,下面做一個(gè)簡(jiǎn)單的介紹:

首先,通過(guò)

View - Tool Windows - Android Profiler 打開(kāi) Android Profiler 。手機(jī)連接電腦后運(yùn)行應(yīng)用,在 Android Profiler 中會(huì)看到以下視圖:

左上角可以選擇設(shè)備和進(jìn)程,點(diǎn)擊 CPU 區(qū)域,即可進(jìn)入CPU Profiler視圖:

左上角可以選擇跟蹤模式:

Sampled:按默認(rèn)采樣率捕獲應(yīng)用的調(diào)用堆棧。該模式的固有問(wèn)題是,如果應(yīng)用在一次捕獲后進(jìn)入一個(gè)函數(shù)并在下一次捕獲前退出該函數(shù),則分析器不會(huì)記錄該函數(shù)調(diào)用。如果對(duì)此類生命周期很短的跟蹤函數(shù)感興趣,可以使用“Instrumented”跟蹤。

Instrumented:以在每個(gè)函數(shù)調(diào)用的開(kāi)始和結(jié)束時(shí)記錄時(shí)間戳。 分析比較時(shí)間戳,以生成函數(shù)跟蹤數(shù)據(jù)。 需要注意的是,設(shè)置與函數(shù)關(guān)聯(lián)的開(kāi)銷會(huì)影響運(yùn)行時(shí)性能,甚至分析數(shù)據(jù),對(duì)于生命周期相對(duì)較短的函數(shù),這一點(diǎn)更為明顯。 此外,如果應(yīng)用短時(shí)間內(nèi)執(zhí)行大量函數(shù),則分析器可能會(huì)迅速超出它的文件大小限制,且不能再記錄更多跟蹤數(shù)據(jù)。

Edit configurations:自定義采樣率。與 traceview 中的 Debug.startMethodTracingSampling() 類似。

.trace 文件的大小是有限制的。對(duì)于給定錄制,當(dāng)分析器到達(dá)該限制時(shí),AS 將停止收集新數(shù)據(jù)(不過(guò),這不會(huì)停止記錄)。 在執(zhí)行“Instrumented”跟蹤時(shí),這種情況通常會(huì)更快發(fā)生,因?yàn)榕c“Sampled”跟蹤相比,此類跟蹤在較短時(shí)間里會(huì)收集更多數(shù)據(jù)。

如果你使用的是Android 8.0(API 26)或更高版本的設(shè)備,則對(duì)于跟蹤數(shù)據(jù)的文件大小沒(méi)有限制,此值可忽略。不過(guò),你仍需留意每次記錄后設(shè)備收集了多少數(shù)據(jù),因?yàn)?AS 可能難以解析大型跟蹤文件。

點(diǎn)擊上方的“開(kāi)始錄制”按鈕,然后在應(yīng)用中操作執(zhí)行被追蹤的功能,結(jié)束后再點(diǎn)擊“停止錄制”按鈕。CPU Profiler 會(huì)自動(dòng)開(kāi)始分析并生成數(shù)據(jù)。

以上就是 CPU Profiler 和 traceview 的使用方法。至于如何制定優(yōu)化方案,就不展開(kāi)了,并沒(méi)有完全固定的路子。就我本例的 onRebuild() 方法而言,是針對(duì)耗時(shí)的Contact構(gòu)造過(guò)程做了并行處理,將上百個(gè)有序的構(gòu)造過(guò)程平分到5個(gè)線程中并發(fā)執(zhí)行,然后再按順序合并數(shù)據(jù)到一個(gè)線程中。最終 onRebuild() 執(zhí)行速度從15秒提升到了2.5秒,對(duì)我來(lái)說(shuō)已經(jīng)夠用了。

重要注意事項(xiàng)

無(wú)論是使用 traceview 還是 CPU Profiler 進(jìn)行函數(shù)跟蹤,有一點(diǎn)需要注意:跟蹤分析過(guò)程中,應(yīng)用的運(yùn)行速度會(huì)減慢。所以,分析數(shù)據(jù)并不能精確反應(yīng)某個(gè)方法在實(shí)際執(zhí)行時(shí)的絕對(duì)時(shí)間。下面是我在優(yōu)化項(xiàng)目中的 onRebuild(boolean) 方法時(shí),記錄的4組數(shù)據(jù),讓我們來(lái)對(duì)比一下:

實(shí)際執(zhí)行時(shí)間:不啟用分析模式,正常運(yùn)行狀態(tài)下通過(guò)打印日志得到的實(shí)際執(zhí)行時(shí)間。

Profiler統(tǒng)計(jì)時(shí)間:使用 CPU Profiler 分析獲得的執(zhí)行時(shí)間。

traceview統(tǒng)計(jì)時(shí)間:通過(guò)分析 traceview 產(chǎn)生的 .trace 文件,從中獲得的執(zhí)行時(shí)間。

traceview實(shí)際時(shí)間:使用 traceview 的情況下,通過(guò)打印日志得到的實(shí)際執(zhí)行時(shí)間。

為什么針對(duì) traceview 會(huì)例舉兩個(gè)時(shí)間呢?這是因?yàn)闇y(cè)試過(guò)程中發(fā)現(xiàn) traceview 自動(dòng)分析出來(lái)的時(shí)間比 實(shí)際執(zhí)行時(shí)間 不僅沒(méi)有慢,反而快了很多,疑惑下又在啟用 traceview 的情況下通過(guò)以下代碼測(cè)算了一下實(shí)際的時(shí)間,這個(gè)倒是真的比 實(shí)際執(zhí)行時(shí)間 慢了。

Debug.startMethodTracing("smssdk_onrebuild");

long curr = System.currentTimeMillis();

onRebuild(true);

Log.d(TAG, "onRebuild lasts: " + (System.currentTimeMillis() - curr));

Debug.stopMethodTracing();

從上表數(shù)據(jù)可見(jiàn),無(wú)論是 CPU Profiler 還是 traceview ,

統(tǒng)計(jì)出來(lái)的時(shí)間都不能準(zhǔn)確代表實(shí)際執(zhí)行時(shí)間。更甚者,traceview自動(dòng)分析出來(lái)的數(shù)據(jù)也與traceview跟蹤模式下實(shí)際的時(shí)間有巨大差別,關(guān)于這一點(diǎn),我沒(méi)找到詳細(xì)的解釋,如果有人知道,還望不吝賜教。

既然跟蹤分析得到的時(shí)間都不能表示實(shí)際的時(shí)間,那么這些數(shù)據(jù)是不是沒(méi)用呢?當(dāng)然不是!它們至少在以下兩個(gè)方面具有價(jià)值:

在一次檢測(cè)得到的數(shù)據(jù)中,線程內(nèi)各個(gè)方法執(zhí)行所耗時(shí)間在整個(gè)線程執(zhí)行時(shí)間中所占比例具有一定參考價(jià)值。占比高的方法當(dāng)是優(yōu)化的重點(diǎn)目標(biāo)。

優(yōu)化前后兩次檢測(cè)得到的數(shù)據(jù),有比較價(jià)值,以確認(rèn)優(yōu)化方案是否真的生效。

通過(guò)這些工具跟蹤函數(shù),也只能做一個(gè)相對(duì)的參考,并不能完全正確的反應(yīng)函數(shù)的執(zhí)行性能。比如我通過(guò) CPU Profiler 獲得的 onRebuild() 方法的分析數(shù)據(jù)顯示,整個(gè)執(zhí)行過(guò)程中 Contact 的構(gòu)造方法占了60%左右,Contact.toString() 方法占了40%左右,但實(shí)際上在 onRebuild() 方法消耗的15秒中,Contact.toString() 只消耗了百毫秒級(jí),而九成以上時(shí)間都被其構(gòu)造方法消耗了,說(shuō)明 CPU Profiler 的監(jiān)控過(guò)程對(duì) Contact.toString() 的性能產(chǎn)生了更大的影響。

而同樣的問(wèn)題卻并沒(méi)有出現(xiàn)在 traceview 的分析結(jié)果中。

請(qǐng)注意,CPU Profiler 和 traceview 不能同時(shí)使用,如果代碼中植入了插樁的代碼,則有可能導(dǎo)致 CPU Profiler 無(wú)法正常開(kāi)始或停止錄制。

traceview 和 CPU Profiler 的對(duì)比

從用法上來(lái)看,traceview 比 CPU Profiler 稍微復(fù)雜一點(diǎn)。類似于MAT需要首先獲取 .hprof 堆轉(zhuǎn)儲(chǔ)文件,traceview 也要首先獲取 .trace 文件,然后使用traceview分析該文件。而 CPU Profiler 則可以直接對(duì)應(yīng)用進(jìn)行分析。

從最終生成的圖表上來(lái)看,CPU Profiler 生成的圖表有 Call Chart、Flame Chart ,它們可以非常形象的表示出線程內(nèi)執(zhí)行了哪些函數(shù),函數(shù)的執(zhí)行時(shí)間,調(diào)用棧等等,一目了然,而且在任意函數(shù)上點(diǎn)擊右鍵,可以直接跳轉(zhuǎn)至對(duì)應(yīng)的代碼,非常方便,在這一點(diǎn)上,相對(duì)于 traceview 要優(yōu)秀。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103110.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<