Android如何打造高質量的應用?( 三)

內存泄漏
內存泄漏簡單來說就是沒有回收不再使用的內存,排查和解決內存泄漏也是內存優化無法避開的工作之一。
很多內存泄漏都是框架設計不合理所導致,各種各樣的單例滿天飛,MVC 中 Controller 的生命週期遠遠大於 View。優秀的框架設計可以減少甚至避免程序員犯錯,當然這不是一件容易的事情,所以我們還需要對內存泄漏建立持續的監控。

Java 內存泄漏。建立類似 LeakCanary 自動化檢測方案,至少做到 Activity 和 Fragment 的泄漏檢測。在開發過程,我們希望出現泄漏時可以彈出對話框,讓開發者更加容易去發現和解決問題。內存泄漏監控放到線上並不容易,我們可以對生成的 Hprof 內存快照文件做一些優化,裁剪大部分圖片對應的 byte 數組減少文件大小。比如一個 100MB 的文件裁剪後一般只剩下 30MB 左右,使用 7zip 壓縮最後小於 10MB,增加了文件上傳的成功率。
OOM 監控。美團有一個 Android 內存泄露自動化鏈路分析組件Probe,它在發生 OOM 的時候生成 Hprof 內存快照,然後通過單獨進程對這個文件做進一步的分析。不過在線上使用這個工具風險還是比較大,在崩潰的時候生成內存快照有可能會導致二次崩潰,而且部分手機生成 Hprof 快照可能會耗時幾分鐘,這對用戶造成的體驗影響會比較大。另外,部分 OOM 是因爲虛擬內存不足導致,這塊需要具體問題具體分析。

OOM 監控。美團有一個 Android 內存泄露自動化鏈路分析組件Probe,它在發生 OOM 的時候生成 Hprof 內存快照,然後通過單獨進程對這個文件做進一步的分析。不過在線上使用這個工具風險還是比較大,在崩潰的時候生成內存快照有可能會導致二次崩潰,而且部分手機生成 Hprof 快照可能會耗時幾分鐘,這對用戶造成的體驗影響會比較大。另外,部分 OOM 是因爲虛擬內存不足導致,這塊需要具體問題具體分析。

Native 內存泄漏監控。上一期我講到 Malloc 調試(Malloc Debug)和 Malloc 鉤子(Malloc Hook)似乎還不是那麼穩定。在 WeMobileDev 最近的一篇文章《微信 Android 終端內存優化實踐》中,微信也做了一些其他方案上面的嘗試。

針對無法重編 so 的情況,使用了 PLT Hook 攔截庫的內存分配函數,其中 PLT Hook 是 Native Hook 的一種方案,後面我們還會講到。然後重定向到我們自己的實現後記錄分配的內存地址、大小、來源 so 庫路徑等信息,定期掃描分配與釋放是否配對,對於不配對的分配輸出我們記錄的信息。

針對可重編的 so 情況,通過 GCC 的“-finstrument-functions”參數給所有函數插樁,樁中模擬調用棧入棧出棧操作;通過 ld 的“–wrap”參數攔截內存分配和釋放函數,重定向到我們自己的實現後記錄分配的內存地址、大小、來源 so 以及插樁記錄的調用棧此刻的內容,定期掃描分配與釋放是否配對,對於不配對的分配輸出我們記錄的信息。

開發過程中內存泄漏排查可以使用 Androd Profiler 和 MAT 工具配合使用,而日常監控關鍵是成體系化,做到及時發現問題。

造成卡頓的原因可能有千百種,不過最終都會反映到 CPU 時間上。我們可以把 CPU 時間分爲兩種:用戶時間和系統時間。用戶時間就是執行用戶態應用程序代碼所消耗的時間;系統時間就是執行內核態系統調用所消耗的時間,包括 I/O、鎖、中斷以及其他系統調用的時間。

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