記憶體效能優化問題
阿新 • • 發佈:2019-01-09
通過檢視onClick的程式碼知道了程式的執行邏輯,startB()是開啟一個新的Activity,startAllocationLargeNumbersOfObjects()是進行大量物件的建立。執行模擬器,效果展示如下:
看看點選之後會通知欄會出現如圖的提示:
既然static有問題,那就直接把static去掉,把sTextView變成非靜態的就可以了。但是這裡面還存在一個不易被發現的記憶體洩漏行為:
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
System.out .println("post delayed may leak");
}
}, 5000);
這裡開啟了一個延時的執行緒,5000ms似乎沒有問題,但是增大後我們可以看到LeakCanary會出現提示匿名介面Runnable持有activity的引用;這時候我們要使用WeakReference來對程式碼進行修改,即實現弱引用,保證可以引用的物件可以被及時垃圾回收;
public static class MyRunnable implements Runnable{
public final WeakReference<MainActivity> mMainActivityWeakReference;
public MyRunnable(MainActivity activity) {
mMainActivityWeakReference = new WeakReference<>(activity);
}
@Override
public void run() {
System.out.println("post delayed may leak");
}
}
但是更改後問題依然存在,但是這次好像和Handler有關,所以將Handler也使用WeakReference進行一下改造
public static class MyHandler extends Handler {
public final WeakReference<MainActivity> mMainActivityWeakReference;
public MyHandler(MainActivity activity) {
mMainActivityWeakReference = new WeakReference<>(activity);
}
}
再來執行一下我們的程式,這次沒有任何記憶體洩漏的提示了。
- 接下來看StartAllocation,連續點選後我們藉助Allocation Tracking可以看到記憶體抖動的現象:
通過Android Studio給我們提供的Allocation Tracking工具進行分析,我們可以看到很多Rect和StringBuilder物件的建立。改進方案是把Rect物件的建立放到成員變數中在onCreate中進行初始化,把String物件建立好,這樣就不會重複建立了。
更改完成後,我們再次執行,問題解決了!