前言:
在開發(fā)項目的過程中 或多或少都有些地方不注意造成內(nèi)存泄漏導致App卡頓的情況發(fā)生 Android Studio也為我們提供了一些查找內(nèi)存泄漏的組件 今天就先學習下 如何使用Android Monitor來分析和查找項目中內(nèi)存泄漏的地方
案例:
public class CommUtil {
private static CommUtil instance;
private Context context;
private CommUtil(Context context) {
this.context=context;
}
public static CommUtil getInstance(Context context){
if(null==instance){
instance=new CommUtil(context);
}
return instance;
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CommUtil instance = CommUtil.getInstance(this);
}
}
將Activity的實例被一個單例對象所持有,相信這樣的代碼錯誤大家應該不會去犯,這里主要學習如何使用Android Monitor 就遷就一下,然后我們運行起來 ,再將手機屏幕旋轉(zhuǎn)幾下(旋轉(zhuǎn)屏幕的時候 Activity會被銷毀重新創(chuàng)建,但是這里的單例會持有銷毀Activity的實例就造成內(nèi)存泄漏)。
-
先看看Android Studio 的Android Monitor都有哪些功能 先只關注Memory這塊
Initiate Gc:點擊主動去回收垃圾內(nèi)存
Dump java Heap: 點擊就會生成app運行內(nèi)存快照.hprof文件
Free :代表還剩下的內(nèi)存
Allocated:代表已經(jīng)使用的內(nèi)存 -
Dump java Heap點擊就會生成app運行內(nèi)存快照.hprof文件
-
通過內(nèi)存快照 看到MainActivity 在內(nèi)存中有3個實例 點擊進行進一步查看
Depth:對象被引用的深度
Shallow Size:對象實例的大小
Dominating Size:對象管轄范圍的內(nèi)存大小 -
在Instance區(qū)域我們看到了MainActivity的3個實例對象 已經(jīng)各個對象的引用深度和大小等 這里就明顯看到了MainActivtiy內(nèi)存泄漏了 這里說明一下 (在運行項目的時候 手機屏幕旋轉(zhuǎn)了3下 所以生成了3個MianActivity實例 但是第二個MainActivity已經(jīng)被回收 因為當GC回收的時候會將除了第0個和最后這一個留著其他的都會被回收 所以當你把手機屏幕旋轉(zhuǎn)3次以上的時候 內(nèi)存里面只會有2個Activity實例)
點擊編號2的MianActivity進行查看:
Depth:對象被引用的深度
Shallow Size:對象實例的大小
Dominating Size:對象管轄范圍的內(nèi)存大小 -
根據(jù)上面的內(nèi)存對象引用樹就能得出結(jié)論分析(除CommUtil以外的地方是系統(tǒng)級的引用這里暫時先不用管) :
- CommUtil引用了MainActivity的context
- 引用深度Depth為1 對象大小為12 該對象管轄范圍大小為60781
然后改代碼:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CommUtil instance = CommUtil.getInstance(getApplicationContext());
}
}
-
該代碼運行 且旋轉(zhuǎn)屏幕后 再生成內(nèi)存快照.hprof文件查看:
將this改為getApplicationContext()后 MainActivity在幾次旋轉(zhuǎn)屏幕后始終保持一個實例
總結(jié):
- 以上是通過已知案例來進行對Android Monitor的簡單學習 在實際開發(fā)過程中還需要去仔細的分析(這個相對來講較困難 需要根據(jù)自己的一些經(jīng)驗來看)
最后:
- 其實還有一個工具叫MAT Memory Analyzer 如何使用在下篇文章進行講解