(Android Studio 3.0)Android Profiler記憶體洩漏檢查
前提概要
記憶體洩漏是常見又重要的問題,針對這個問題谷歌在Android Studio 3.0中推出了Android Profiler。筆者此篇文章主要記錄一下Android Profiler在記憶體洩漏方面的使用。
Android Profiler
Android Profiler在Android Studio左下角,需要在Android Studio 3.0及其以上才會有。如果是Android Studio 3.0並且也未有這個按鈕,讀者也不用著急,執行一下自己的專案就會出現。當點選MEMORY那一行的時候就能進入記憶體檢查的介面。
接下來筆者通過分析記憶體洩漏的例項的方式來介紹Android Profiler的使用。
例項
主要是三個Activity:MainActivity,ActivityOne,ActivityTwo。
MainActivity:主Activity,用於開啟記憶體洩漏的兩個Activity。
ActivityOne:通過handler方式洩漏。
ActivityTwo:通過靜態引用方式洩漏。
程式碼如下:
MainActivity:
public class MainActivity extends AppCompatActivity {
public static Activity activity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
Button btnOne=findViewById(R.id.btn_one);
btnOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,ActivityOne.class);
startActivity(intent);
}
});
Button btnTwo=findViewById(R.id.btn_two);
btnTwo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,ActivityTwo.class);
startActivity(intent);
}
});
}
}
ActivityOne:
public class ActivityOne extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
}
},1000000);
}
}
ActivityTwo:
public class ActivityTwo extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivity.activity=this;
}
}
記憶體洩漏分析
操作
首先我們開啟MainActivity,分別開啟ActivityOne和ActivityTwo並退出,回到MainActivity。接著開啟Android Profiler。
檢查記憶體洩漏物件
首先要點選左上方的“Dump Java heap”按鈕。(如果是檢查記憶體洩漏,筆者建議在點選之前先點選垃圾回收按鈕,以防可回收的存貨物件的混淆)
然後就會顯示此刻的JAVA堆中物件以及引用情況,我們可以在Heap Dump的右上角選擇物件的排列方式,筆者比較推薦按報名排序,因為一般我們檢查的都是自己所寫的類的洩漏,而非系統層的。
如圖,我們很快就發現ActivityOne和ActivityTwo洩漏了。
筆者開啟了ActivityOne和ActivityTwo之後,回到MainActivity介面並按下垃圾回收按鈕。不洩露的情況應該是隻有MainActivity被分配了記憶體,而ActivityOne和ActivityTwo均存活,說明記憶體沒有被釋放,即記憶體洩漏了。
Heap Dump 右邊四列的意思分別如下:
Alloc Count:Java堆中的例項個數
Native Size:native層分配的記憶體大小。
Shallow Size:Java堆中分配實際大小
Retained Size:這個類的所有例項保留的記憶體總大小(並非實際大小)
在記憶體洩漏檢查的過程中,筆者也出現過理論上物件應該被回收,卻仍保留的情況。一般情況下,如果Shallow Size和Retained Size都非常小並且相等,都可以認為是已經被回收的物件。因為系統已經不認為它會被用到,並且沒有給它保留分配的記憶體。
解決記憶體洩漏(方法一)
繼續我們在Heap Dump介面的操作,以檢查ActivityOne為例,我們單擊它,發現右側出現了Instance View,然後單擊Instance View的物件。
在Instance View中,會顯示在ActivityOne中的各種物件,而它下方的Reference則是顯示諸多對這個存貨的ActivityOne物件的引用。大部分都是系統層面的引用,只有一個格外顯眼,就是通過“this”對ActivityOne的引用,點進去我們可以發現是MessageQueue持有了這個引用,有點經驗的Android程式設計師馬上可以定位到是Handler的記憶體洩漏了。
解決記憶體洩漏(方法二)
第一種記憶體洩漏的檢查方法由於有過多的系統引用的混淆,相信並不讓人覺得容易上手。這時候相信讀者會想嘗試第三個錄製按鈕了。
Record memory allocations:
這個按鈕的作用是記錄一段時間內的記憶體分配的內容,點選紅色的小圓表示開始錄製,點選小正方形是結束錄製。(錄製時間不建議超過10s,計算記憶體會很慢)
操作
首先重新執行APP,停留在MainActivity介面,然後點選紅色小圓按鈕開始錄製,接著分別開啟ActivityOne和ActivityTwo然後退出,回到MainActivity介面,最後點選小正方形結束錄製。
解決記憶體洩漏
然後我們仍然是按照包名排列,找到記憶體洩漏的物件。
然後我們選擇ActivityOne,再單擊Instance View 中的這個物件。我們可以發現,完全能再程式碼中追蹤到這個引用建立的地方。
我們雙擊Call Stack中的第一行,發現可以直接跳轉到程式碼記憶體洩漏的地方。
兩者優劣
解決記憶體洩漏方法一:
1、可以用於檢查記憶體洩漏,並不僅僅是檢視引用情況。
2、不需要定位引用的建立時間,因為檢視的是java堆該時的狀態。
3、不可以定位到相關程式碼。
4、系統引用也會顯示,容易混淆。
解決記憶體洩漏方法二:
1、可以直接定位到相關程式碼。
2、不會有過多的系統引用混淆。
3、需要定位物件建立的時間,在記憶體記錄的時間內進行操作才會顯示。
總結
Android Profiler只是解決記憶體洩漏的一個工具,在一些情況下無法定位到相關程式碼。比如以下情況:
A a=A();
……
c=a;
在這種情況下,如果A類洩漏,那麼程式碼只能定位到 “A a=A();”,而下面的間接引用卻無法由Android Profiler體現出來,這就需要讀者通過閱讀原始碼來自行解決了。
總之也算是孰能生巧,新工具固然能提高我們的效率,但是還是無法替代手動檢查的工作。
相關文章
- Android 記憶體洩漏Android記憶體
- Android記憶體洩漏Android記憶體
- Android檢測記憶體洩漏之leakcanaryAndroid記憶體
- Android 記憶體洩漏分析Android記憶體
- Android記憶體洩漏場景Android記憶體
- Android中的記憶體洩漏Android記憶體
- Android 記憶體洩漏總結Android記憶體
- ANTS Memory Profiler - .NET記憶體洩漏分析工具記憶體
- Android中常見的記憶體洩漏Android記憶體
- Android備忘錄《記憶體洩漏》Android記憶體
- 初步探究Android記憶體洩漏(1)Android記憶體
- Android中的記憶體洩漏模式Android記憶體模式
- Android 5.1 WebView記憶體洩漏分析AndroidWebView記憶體
- Android 記憶體洩漏案例和解析Android記憶體
- 如何檢查Javascript中的記憶體洩漏JavaScript記憶體
- 基於Android Studio的記憶體洩漏檢測與解決全攻略Android記憶體
- Android 輕鬆解決記憶體洩漏Android記憶體
- Android常見記憶體洩漏總結Android記憶體
- Android Handler機制之記憶體洩漏Android記憶體
- 全面總結Android記憶體洩漏(下)Android記憶體
- Android效能優化之記憶體洩漏Android優化記憶體
- Android 記憶體洩漏的八種可能Android記憶體
- Android記憶體洩漏的8種可能Android記憶體
- Android WebView Memory Leak WebView記憶體洩漏AndroidWebView記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(上)Android優化記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(下)Android優化記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(中)Android優化記憶體
- iOS檢測記憶體洩漏iOS記憶體
- 如何檢測記憶體洩漏記憶體
- Android 檢測記憶體洩露Android記憶體洩露
- 如何查詢記憶體洩漏記憶體
- Android記憶體優化(三)避免可控的記憶體洩漏Android記憶體優化
- 使用新版Android Studio檢測記憶體洩露和效能Android記憶體洩露
- 防止 Android 記憶體洩漏的 8 種方法Android記憶體
- [貝聊科技]使用Android Studio和MAT進行記憶體洩漏分析Android記憶體
- Android效能優化篇之記憶體優化--記憶體洩漏Android優化記憶體
- JavaScript記憶體洩漏檢測工具JavaScript記憶體
- 記憶體洩漏記憶體