記錄 Java/Kotlin 配置有助於找出可能導致效能問題的不理想記憶體模式。分析器會顯示下列物件配置相關資訊:
- 配置的物件類型及其記憶體用量。
- 每項配置的堆疊追蹤,包括其執行緒所在位置。
- 物件取消分配的時間。
您應記錄正常與極端使用者互動情況下的記憶體配置,以明確找出程式碼是否在短時間內配置過多目標物件,或所配置的目標物件發生記憶體流失。進一步瞭解為什麼您必須分析應用程式記憶體。
如何記錄 Java/Kotlin 配置
如要記錄 Java/Kotlin 配置,請從分析器的「首頁」分頁選取「追蹤記憶體消耗量 (Java/Kotlin 配置)」工作。請注意,您需要可偵錯的應用程式 (使用「分析器:以可偵錯模式執行『app』(完整資料)」),才能記錄 Java/Kotlin 分配情形。
根據預設,Android Studio 會擷取記憶體中的所有物件配置。如果您的應用程式會配置大量物件,在分析作業期間可能會發生效能明顯遲緩的情形。如要提升分析作業期間的效能,請前往「配置追蹤」下拉式選單,然後選取「取樣」,而非「完整」。 取樣時,分析器會定期收集記憶體中的物件配置。
如要在錄製期間強制執行垃圾收集事件,請按一下垃圾桶圖示 。
Java/Kotlin 配置總覽
停止錄製後,你會看到以下畫面:
- 事件時間軸會顯示活動狀態、使用者輸入內容事件和螢幕旋轉事件。
- 記憶體用量時間軸會顯示下列資訊。選取時間軸的某個部分,即可篩選特定時間範圍。
- 堆疊長條圖,顯示每個記憶體類別目前的記憶體用量,以左側 y 軸和頂端的色彩索引鍵表示。
- 虛線,顯示已配置的物件數量,以右側 y 軸表示。
- 代表每個垃圾收集事件的圖示。
- 「表格」分頁會顯示課程清單。「Total Count」是所選時間範圍結束時的分配次數 (「Allocations」減去「Deallocations」),因此建議您先偵錯「Total Count」值最高的類別。如果想根據所選時間範圍內的尖峰配額,優先排解課程問題,請依「配額」排序。同樣地,「Remaining Size」是「Allocations Size」減去「Deallocations Size」所得的結果,以位元組為單位。
- 在「Table」(表格) 清單中按一下類別時,系統會開啟「Instance」(例項) 窗格,並列出相關聯的物件,包括物件的分配時間、取消分配時間和淺層大小。
「視覺化」分頁會匯總顯示所選時間範圍內,呼叫堆疊中的所有物件。基本上,這會顯示呼叫堆疊與所顯示執行個體佔用的總記憶體量。第一列顯示執行緒名稱,根據預設,物件會根據配置大小從左到右堆疊;使用下拉式選單即可變更排序方式。
使用堆積下拉式選單,篩選特定堆積。除了擷取堆積傾印時可用的篩選器,您也可以篩選 JNI 堆積中的類別。JNI 堆積會顯示 Java Native Interface (JNI) 參照的配置位置和發布位置。
使用「配置」下拉式選單選擇分配方式。除了擷取堆積傾印時可用的排列方式,您也可以依呼叫堆疊排列。
記憶體的計算方式
頂端顯示的數字是根據 Android 系統中應用程式提交的所有專用記憶體頁面。這個總數不包含與系統或其他應用程式共用的頁面。記憶體總數可分為以下類別:
- Java:這類記憶體來自透過 Java 或 Kotlin 程式碼配置的物件。
Native:這類記憶體來自透過 C 或 C++ 程式碼配置的物件。
即使您不是使用 C++ 來編寫應用程式,這裡仍可能會顯示一些原生記憶體,這是因為 Android 架構會使用原生記憶體代您處理各項工作,例如處理圖片資源和其他圖像 (即使您使用 Java 或 Kotlin 編寫程式碼)。
Graphics:讓圖像緩衝區佇列在螢幕上顯示像素 (包括 GL 表面、GL 材質等) 時所用的記憶體 請注意,這類記憶體會與 CPU 共用,並不是專屬 GPU 記憶體。
堆疊:應用程式中由原生堆疊和 Java 堆疊使用的記憶體。這通常與應用程式執行的執行緒數量有關。
程式碼:應用程式用來處理程式碼和資源 (例如 DEX 位元碼、經過最佳化或編譯過的 DEX 程式碼、
so
程式庫和字型。Others:由應用程式使用但系統不確定如何分類的記憶體。
已配置:應用程式配置的 Java/Kotlin 物件數量。這不會計入 C 或 C++ 中配置的物件。
檢查分配記錄
如要檢查配置記錄,請按照下列步驟操作:
- 在「表格」分頁中瀏覽類別清單,找出「配置」或「總計數」值異常大的物件 (視您要最佳化的項目而定),這些物件可能已流失。
- 在「Instance View」窗格中,點選某個執行個體。視該例項的適用情形而定,系統會開啟「欄位」或「分配呼叫堆疊」分頁。使用「欄位」或「配置呼叫堆疊」分頁中的資訊,判斷執行個體是否真的有必要,或只是不必要的重複項目。
在任何清單項目上按一下滑鼠右鍵,即可跳至相關原始碼。
查看全域 JNI 參照
Java Native Interface (JNI) 是一種架構,可讓 Java 程式碼和原生程式碼互相呼叫。JNI 參照是透過原生程式碼手動管理,因此可能會發生下列問題:
- 系統保留原生程式碼使用的 Java 物件時間過長。
- 如果未先明確刪除就捨棄 JNI 參照,Java 堆積上的部分物件可能會無法存取。
- 全域 JNI 參照已達上限。
如要排解這類問題,請在分析器中選取「查看 JNI 堆積」,瀏覽所有全域 JNI 參照,並依 Java 型別和原生呼叫堆疊進行篩選。在「Fields」分頁中,對例項欄位按一下滑鼠右鍵,然後選取「Go to instance」,即可查看相關的分配呼叫堆疊。
「Allocation Call Stack」分頁會顯示 JNI 參照在程式碼中的配置和發布位置。
如要進一步瞭解 JNI,請參閱「JNI 提示」。