Android效能優化典範
後期我會面試50家網際網路公司,不斷總結完善和思考,寫出一本完美的安卓面試書籍,大家支援我嗎?
目錄
1、記憶體優化
2、ui優化
3、網路優化
4、啟動優化
1、記憶體優化
1.1、解決所有的記憶體洩漏
1.1.1、記憶體洩漏:
堆上分配的物件已經不會再使用,但是GC收集器無法對其進行回收,此物件被強應用所引用 。
1.1.2、GC收集器原理:
可達性演算法:從GCRoot物件為起點,向下搜尋,可到達的物件是稱為GC可達,GC收集器不會回收,不可到達的物件稱為不GC不可達,是GC收集器回收的物件。
GCRoot物件:
(1)、虛擬機器棧(棧幀找那個的區域性變量表)中的物件;
(2)、方法區中類靜態變數引用的物件;
(3)、方法區中常量引用的物件。
1.1.3、常見的記憶體洩漏例項
(1)、單例造成的記憶體洩漏

單例造成記憶體洩漏
單例類的例項是靜態的,如果需要其構造方法需要傳遞一個context,如果傳入的是 Activity 的 Context,當傳入 Activity 就會造成洩漏了。
解決方法:this.context = context.getApplicationContext();// 使用Application 的context。
(2)、內部類造成的記憶體洩漏

內部類建立靜態物件導致記憶體洩漏
在Activity中有一個內部類,如果建立了這個內部類的靜態物件,Activity關閉的時候,由於內部類會持有外部類的引用,內部類靜態物件會持有外部類Activity的引用,導致Activity發生記憶體洩漏。
解決方法:將該內部類設為靜態內部類,如果該內部類需要持有外部類的引用,則使用軟引用/弱引用,在使用外部類的引用之前需進行空判斷。
(3)、非同步執行緒造成的記憶體洩漏

非同步執行緒造成記憶體洩漏
在Activity中有一個開啟一個執行緒執行一個runnable,這個runnable是內部類就會持有外部類Activity的引用,如果執行緒的生命週期比Activity的生命週期長,就不會導致Activity記憶體洩漏。
解決方法:同上
(4)、Handler 造成的記憶體洩漏

handler造成記憶體洩漏
在Activity中宣告一個內部類handler,當使用這個handler傳送一個延遲訊息時,此訊息執行前,Activity關閉會造成記憶體洩漏。
解決方法:同上
(5)資源未關閉造成記憶體洩漏
對於使用了BraodcastReceiver,ContentObserver,File,遊標 Cursor,Stream,Bitmap等資源的使用,應該在Activity銷燬時及時關閉或者登出,否則這些資源將不會被回收,造成記憶體洩漏。
1.1.4、記憶體洩漏檢測方案
LeakCanary原理:
-
LeakCanary在一個Fragment或者Activity onDestory的時候,建立一個弱引用
KeyedWeakReference
到要被監控的物件。 -
然後在後臺執行緒檢查引用是否被清除,如果沒有,呼叫GC。
-
如果引用還是未被清除,把 heap 記憶體 dump 到 APP 對應的檔案系統中的一個
.hprof
檔案中。 -
在另外一個程序中的
HeapAnalyzerService
有一個HeapAnalyzer
使用 ofollow,noindex">HAHA 解析這個檔案。 -
得益於唯一的 reference key,
HeapAnalyzer
找到KeyedWeakReference
,定位記憶體洩露。 -
HeapAnalyzer
計算 到 GC roots 的最短強引用路徑,並確定是否是洩露。如果是的話,建立導致洩露的引用鏈。
1.2、避免記憶體抖動
記憶體抖動代表頻繁GC,會佔用程式執行時間,造成頁面卡頓等效能問題。
1.2.1、避免記憶體抖動的方式:
(1)、避免在onDraw中建立Paint、Bitmap物件等;
(2)、避免在迴圈中建立臨時物件;
(3)、避免在scrollListener中建立物件。
1.3、記憶體抖動檢測方法
(1)、使用Android profiler 進行觀察,如果發下記憶體劇增劇減則是GC時間,可檢視GC時間段的記憶體,找出重複建立的大量物件,進行優化(例子:在recycleview中獲取距離螢幕的距離時,建立大量物件)。
1.3、圖片優化
(1)、網路圖片:使用網路裁剪服務,獲取適當的圖片載入。
(2)、本地圖片:使用Tinypng深度壓縮,必要時進行裁剪。
(3)、使用web格式代替png、jpeg格式。
(4)、使用Fresco對圖片進行管理。
1.3.1、fresco對記憶體的管理:
(1)、在5.0以下系統,Bitmap快取位於ashmem,這樣Bitmap物件的建立和釋放將不會引發GC,更少的GC會使你的APP執行得更加流暢。5.0及其以上系統,相比之下,記憶體管理有了很大改進,所以Bitmap快取直接位於Java的heap上。
(2)、當應用在後臺執行時,該記憶體會被清空。
1.4、使用優化的資料結構
2、ui優化
2.1、分析佈局,減少佈局巢狀或者替換消耗效能少的佈局
2.2、使用include+merge減少佈局層級
2.3、使用viewstub提供按需載入
3、網路優化
3.1、網路速度:
正常一條網路請求需要經過的流程是這樣:
(1)、DNS 解析,請求DNS伺服器,獲取域名對應的 IP 地址;
(2)、與服務端建立連線,包括 tcp 三次握手,安全協議同步流程;
(3)、連線建立完成,傳送和接收資料,解碼資料。
這裡有明顯的三個優化點:
3.1、IP直連或者HTTPDNS;
3.2、開啟 keep-alive進行連線複用;
3.3、減少請求和返回資料的大小;
(1)、請求和返回資料做Gzip壓縮;
(2)、精簡資料格式;
(3)、按需載入圖片(圖片裁剪,也可按網路狀態返回不同解析度的圖片);