Android MAT內存泄露分析


結合《Android開發藝術探索》書籍中的內存分析例子來講解如何利用MAT工具來查找內存泄漏(以AndroidStudio開發工具為例)。

1、下載MAT(Eclipse Memory Analyzer)工具,windows64位網盤下載地址:http://pan.baidu.com/s/1pLlbOBD,或者通過官網下載:https://www.eclipse.org/mat/downloads.php,下載完畢后解壓即可,目錄結構如下:

2、模擬內存泄漏的場景,源碼如下,啟動退出三次app即可。

  代碼結構如下

MainActivity.java
package androidstudy.androidartstudy05;

import android.content.Context;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import androidstudy.androidartstudy05.manager.TestManager;

public class MainActivity extends AppCompatActivity implements TestManager.OnDataArrivedListener {
private static final String TAG = "MainActivity";

private static Context sContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

sContext = this;
TestManager.getInstance().registerListener(this);
}

private synchronized void testANR() {
SystemClock.sleep(30 * 1000);
}

private synchronized void initView() {

}

@Override
public void onDataArrived(Object data) {
Log.i(TAG, data.toString());
}
}
TestManager.java
package androidstudy.androidartstudy05.manager;

import java.util.ArrayList;
import java.util.List;

/**
* Created by Administrator on 2016/7/19.
*/
public class TestManager {
private List<OnDataArrivedListener> mOnDataArrivedListeners = new ArrayList<OnDataArrivedListener>();

private static class SingletonHolder {
public static final TestManager INSTANCE = new TestManager();
}

private TestManager() {
}

public static TestManager getInstance() {
return SingletonHolder.INSTANCE;
}

public synchronized void registerListener(OnDataArrivedListener listener) {
if (!mOnDataArrivedListeners.contains(listener)) {
mOnDataArrivedListeners.add(listener);
}
}

public synchronized void unregisterListener(OnDataArrivedListener listener) {
mOnDataArrivedListeners.remove(listener);
}

public interface OnDataArrivedListener {
public void onDataArrived(Object data);
}
}
3、點擊AndroidStudio界面的Monitor按鈕打開DDMS界面,如下圖所示,點擊Dump HPROF file(紅色框框標記)按鈕導出一個hprof后綴的文件androidstudy.androidartstudy05.hprof保存到platform-tools下(放到此目錄是為了下一步方便轉換文件),我的路徑為E:\Android\sdk\platform-tools

4、由於導出后的文件不能直接被MAT識別,所以需要通過hprof-conv命令轉換一下,此命令是Android SDK提供的工具,位於platform-tools下,cmd命令切換到此目錄后輸入hprof-conv androidstudy.androidartstudy05.hprof androidstudy.androidartstudy05-conv.hprof命令回車,
會在platform-tools目錄下生成一個androidstudy.androidartstudy05-conv.hprof文件,如下圖:

5、打開MAT工具,導入轉換后的文件androidstudy.androidartstudy05-conv.hprof,打開后界面如下:

6、點擊“Histogram”按鈕,展示界面如下,在紅色框框中輸入應用的包名androidstudy.androidartstudy05

7、通過下圖結果可以看到MainActivity對象有三個(正常只會出現一個),很明顯MainActivity存在內存泄漏

8、在MainActivity上點擊右鍵->"Merge Shortest Paths To GC Roots"->"exclude all phantom/weak/soft etc.refrences"。

9、在打開的界面即可看到詳細的引用詳情

10、可以看到有三處引用了MainActivity對象,兩處為單例對像列表(List<OnDataArrivedListener>)屬性mOnDataArrivedListeners 持有,一處為靜態變量private static Context sContext持有

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM