1. 程式人生 > 其它 >效能測試——如何使用Android Studio的Profiler工具進行效能測試

效能測試——如何使用Android Studio的Profiler工具進行效能測試

文章目錄:

  1. 什麼是效能測試
  2. 為什麼要做效能測試
  3. App效能測試指標是什麼
  4. 如何使用Profiler工具進行效能測試——以結對程式設計作業為例
  5. 關於App效能優化的一些建議

1. 什麼是效能測試
效能測試針對系統的效能指標,建立效能測試模型,制定效能測試方案,制定監控策略,在場景條件之下執行效能場景,分析判斷效能瓶頸並調優,最終得出效能結果來評估系統的效能指標是否滿足既定值。
2. 為什麼要做效能測試
1)目前絕大多數應用都是基於網路的分散式應用,我們無法知道使用者數量,使用者場景的不確定性,導致系統測試時,不僅僅是功能,業務邏輯,介面測試,還要測試系統性能。一個使用者沒問題,但是使用者一旦多了就可能出現各種各樣的問題,所以需要進行系統性能測試。
2)使用者數量增加,系統負載增加,進行系統性能測試,知道系統承受的併發使用者數量,頻寬是否夠用,cpu是否夠用,記憶體是否夠用,硬碟速度是否跟得上。從服務端來看,測試伺服器是否能承載使用者多併發,系統是否穩定,從使用者角度看響應時間速度。
3. App效能測試指標是什麼

  1. APP啟動速度(啟動時間)
  2. CPU的佔用量
  3. 電量消耗
  4. 記憶體佔用
  5. FPS(每秒傳輸幀率)直接反應APP流暢度
  6. 流量
  7. CPU過度渲染

在Profiler裡,主要的效能指標有:cpu佔用、記憶體佔用、流量、電量消耗。由於我的app不涉及聯網功能,我們將重點圍繞cpu、記憶體展開測試。
4. 如何使用Profiler工具進行效能測試
4.1 Profiler使用流程
開啟Android studio,選擇結對程式設計的專案,點選介面右上角的速度表圖示或者左下角的Profiler圖示,彈出Profiler工具介面,如下圖所示

現在我們沒有執行虛擬機器,也沒有讀取捕獲的片段,所以介面是空的。
現在單擊執行按鈕,啟動虛擬機器並執行我們的app。可以看到,程序被自動載入到了profiler當中。左邊是我們正在執行的程序,右邊是實時的效能資料。我們可以清楚地看到虛擬機器的實時執行情況。

介面中繪製了四張曲線圖,分別對應CPU(處理器)、Memory(記憶體)、Network(網路)、Energy(耗電)四個指標,想要檢視某個指標的具體資訊,只需要點選曲線圖即可。
下面介紹不同效能指標工具的詳細使用。
4.2 CPU分析工具(CPU Profiler)


進入Cpu Profiler,我們可以看到如下介面。

它會立即開始顯示應用程式的CPU使用率和執行緒的活動
CPU Profiler的預設檢視包含以下內容:
①:Event timeline:顯示應用在他們的生命週期中不同狀態間轉換時的活動,並指示使用者與裝置的互動,包括螢幕旋轉事件
②:CPU timeline:顯示應用程式的實時CPU使用情況(佔可用CPU總時間的百分比)以及應用程式正在使用的執行緒總數。時間表還顯示了其他程序(如系統程序或其他應用程式)的CPU使用情況,因此您可以將其與應用程式的使用情況進行比較。可以通過沿著時間軸的橫軸移動滑鼠來檢查歷史CPU使用率資料。
③:Thread activity timeline:列出屬於你的應用程式程序的每個執行緒,並使用下面列出的顏色在時間線上指示其活動。記錄方法跟蹤之後,可以從此時間線中選擇一個執行緒,以在跟蹤窗格中檢查其資料。
綠色:執行緒處於活動狀態或準備好使用CPU。也就是說,它處於“執行”或“可執行”狀態。
黃色:執行緒處於活動狀態,但它正在等待I / O操作(例如磁碟或網路I / O),然後才能完成工作。
灰色:執行緒正在休眠,不佔用任何CPU時間。當執行緒需要訪問尚不可用的資源時,有時會發生這種情況。執行緒進入自願睡眠,或者核心使執行緒進入休眠狀態,直到需要的資源變為可用。
④:Recording configurations:允許您選擇以下選項之一來確定探查器如何記錄方法跟蹤。
Sampled(取樣):一個預設配置,可以在應用程式執行期間頻繁地捕獲應用程式的呼叫堆疊。分析器比較捕獲的資料集合以獲取關於應用程式碼執行的時間和資源使用資訊。基於抽樣的跟蹤的一個固有問題是,如果您的應用程式在捕獲呼叫堆疊之後輸入方法,並在下次捕獲之前退出該方法,則該方法呼叫不會被分析器記錄。如果您對如此短的生命週期跟蹤方法感興趣,則應使用檢測跟蹤。
Instrumented:預設配置,在執行時測試您的應用程式,以在每個方法呼叫的開始和結束時記錄一個時間戳。收集時間戳並進行比較,以生成方法跟蹤資料,包括定時資訊和CPU使用情況。請注意,與每種方法相關的開銷都會影響執行時效能,並可能影響分析資料 - 對於生命週期相對較短的方法來說,這一點更為明顯。此外,如果您的應用程式在很短的時間內執行大量方法,分析器可能會快速超出其檔案大小限制,並且無法記錄任何進一步的跟蹤資料。
Edit configurations:允許您更改上述取樣和檢測記錄配置的某些預設設定,並將其儲存為自定義配置。
⑤:Record button:開始和停止錄製方法跟蹤按鈕
記錄和檢查方法跟蹤

對於應用程式程序中的每個執行緒,你可以找到在一段時間內執行哪些方法以及每個方法在執行期間消耗的CPU資源。你還可以使用方法跟蹤來識別呼叫者和被呼叫者,呼叫者是一種呼叫另一種方法的方法,被呼叫方是另一種方法呼叫的方法。你可以使用此資訊來確定哪些方法太頻繁地呼叫特定資源繁重的任務,就可以嘗試優化應用程式的程式碼以避免不必要的工作。
要開始記錄方法跟蹤,從下拉選單中選擇Sampled或Instrumented型別,然後單擊Record開始進行記錄,完成後點選Stop recording停止記錄。profiler自動選擇記錄的時間幀,並在方法跟蹤窗格中顯示它的跟蹤資訊,如下圖所示。如果要檢查不同執行緒的方法跟蹤,只需從執行緒活動時間軸中選擇它。

app生成1000道題的記錄情況如下:

點選執行緒左邊的小三角可以檢視詳細資訊。
主執行緒的資訊如下:

點選方法對應的長條還會顯示方法的具體資訊。長方形越長代表方法耗時越久。

4.3 記憶體分析工具(Memory Profiler)
可以通過左上角的下拉選單切換不同的工具。我們選擇Memory。

預設顯示的介面如下:

記憶體剖析器的預設檢視包括以下內容:
①:強制執行垃圾收集事件的按鈕
②:捕獲堆轉儲的按鈕
③:一個記錄記憶體分配的按鈕,當連線到執行Android7.1或更低的裝置時,該按鈕才會出現
④:放大/退出時間線按鈕
⑤:可以跳轉到實時記憶體資料的按鈕。
⑥:事件時間軸,顯示活動狀態、使用者輸入事件和螢幕旋轉事件。
⑦:記憶體使用時間線,包括以下內容:一個堆疊圖,顯示每個記憶體類別的記憶體大小,如左側的y軸和頂部的顏色鍵。虛線表示已分配物件的數量,如右側的y軸所示。每個垃圾收集事件的圖示
記憶體計算指標
左上角能看到一欄資料,顯示了不同的記憶體計算指標。

它們分別代表以下內容:
Java:從Java或Kotlin程式碼中分配的物件的記憶體
Native:從C或c++程式碼中分配的物件的記憶體,即使你沒有在app中使用c++,你可能會看到一些本地記憶體,因為Android框架使用Native記憶體來處理各種任務,比如處理影象資產和其他圖形——即使你寫的程式碼是Java或Kotlin
Graphics:用於圖形緩衝區佇列的記憶體用於顯示螢幕上的畫素,包括GL表面、GL紋理等。(注意,這是與CPU共享的記憶體,而不是專用的GPU記憶體)
Stack:在你的應用程式中,Native和Java棧使用的記憶體。這通常與你的應用程式執行的執行緒數有關
Code:您的應用程式用於程式碼和資源的記憶體,如dex位元組碼,優化或編譯的dex程式碼。所以庫和字型
Other:應用程式使用的記憶體,系統不確定如何分類
Allocated:應用程式分配的Java/Kotlin物件的數量。這並不計算用C或c++分配的物件
記錄某一時刻的記憶體分配情況
如果我們想要記錄app在某段時間的記憶體佔用情況,應該怎麼做呢。
方法很簡單。選擇左邊錄製選項中的Record Java/Kotlin allocations,點選Record,工具便開始記錄記憶體佔用情況。

需要結束錄製時,點選紅色圓圈即可。

隨後錄製結果便會被儲存,你可以在左側選單中找到它,點選便可檢視記錄的資料。

以生成題目的過程為例,記錄的記憶體佔用如下:

或者你也可以以視覺化圖形的方式展現記憶體佔用情況,我個人更加喜歡這種方式。

將滑鼠懸停在彩色長方形上,我們可以很清楚地看到不同的類佔用的記憶體大小,長方形越長,記憶體佔用越大。
以我的app為例,我可以看到,在我自己編寫的類中,GeneratorFragment佔用了最多的記憶體。以此為依據,我們便可以針對性地優化個別模組。

5.關於App效能優化的一些建議
除了利用效能測試工具分析應用效能,尋找優化空間,開發者在開發過程中,就應該注意一些效能優化技巧,養成良好的開發習慣,減輕效能優化的負擔。
下面是一些優化建議:

  1. 在LinearLayout和RelativeLayout都可以完成佈局的情況下優先選擇LinearLayout,可以減少View的層級,但是注意相同元件可能RelativeLayout繪製時間長
    
  2. onDraw中不要建立新的區域性物件,onDraw方法中不要做耗時的任務。
    
  3. 不要在主執行緒進行網路訪問/大檔案的IO操作。
    
  4. 繪製UI時,儘量減少繪製UI層次;減少不必要的view巢狀。
    
  5. 當我們的佈局是用的FrameLayout的時候,我們可以把它改成merge,可以避免自己的幀佈局和系統的ContentFrameLayout幀佈局重疊造成重複計算(measure和layout)。
    
  6. 在view層級相同的情況下,儘量使用 LinerLayout而不是RelativeLayout;因為RelativeLayout在測量的時候會測量二次,而LinerLayout測量一次,可以看下它們的原始碼。
    
  7. 刪除控制元件中無用的屬性。
    
  8. 佈局複用.比如listView 佈局複用。
    
  9. 儘量避免過度繪製(overdraw),比如:背景經常容易造成過度繪製。由於我們佈局設定了背景,同時用到的MaterialDesign的主題會預設給一個背景。這時應該把主題新增的背景去掉;還有移除XML 中非必須的背景。
    
  10. 自定義View優化。使用 canvas.clipRect()來幫助系統識別那些可見的區域,只有在這個區域內才會被繪製。也是避免過度繪製。
    
  11. 啟動優化,啟動速度的監控,發現影響啟動速度的問題所在,優化啟動邏輯,提高應用的啟動速度。比如閃屏頁面,合理優化佈局,載入邏輯優化,資料準備。
    
  12. 合理的重新整理機制,儘量減少重新整理次數,儘量避免後臺有高的 CPU 執行緒執行,縮小重新整理區域。