我们就需要使用mat进行分析,打开以后如下图,
mat下载地址:http://www.eclipse.org/mat/downloads.php
本文以单例模式 内存泄漏为例子
public class PendingOrderManager {
private static PendingOrderManager instance;
private Context mContext;
public PendingOrderManager(Context context) {
this.mContext = context;
}
public static PendingOrderManager getInstance(Context context) {
if (instance == null) {
instance = new PendingOrderManager(context);
}
return instance;
}
}
BActivity.class
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.w("TAG", "-----BActiviy onCreate---------");
setContentView(R.layout.content_main);
textView = findViewById(R.id.sex_tv);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
PendingOrderManager.getInstance(BActivity.this);
}
内存快照查看 查找内存泄漏
运行后 打开BActivity 然后关闭
在Android Profile 里面查看Memory,点击某一时刻,可以查看堆内存里面存在的对象
打开BActivity 后 再关闭,此时抓取内存快照,然后导出
这时候会生成一个hprof文件
导出以后我们会得到.hprof文件,但是这个不是mat工具用到的标准文件。我们需要使用sdk自带的hprof-conv.exe(platform-tools文件夹下) 工具进行转换,转换以后我们就得到了mat.hprof文件
进入Android sdk 目录下的hprof-conv.exe 里面 执行 hprof_conv -z
例如
C:\Users\Administrator>E:\AndroidTool\SDK\Androidsdk\platform-tools\hprof-conv.exe hprof-conv
-z E:\memory1.hprof E:\mat.hprof
如果将\hprof-conv.exe配置环境变量,则在任何地方都可以使用,比较方便
hprof-conv.exe 文件的位置
C:\Users\Administrator>E:\AndroidTool\SDK\Androidsdk\platform-tools\hprof-conv.exe
转换之前的文件位置
E:\memory1.hprof
转换之后的文件位置
E:\mat.hprof
- Histogram可以列出内存中的对象,对象的个数以及大小。
- Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。
- Top consumers通过图形列出最大的object。
- Leak Suspects通过MA自动分析泄漏的原因。
点击Histogram
可以看到BActivity 自身有288(Shallow Heap)大小,引用其他的对象大于4416(Retained Heap)
将鼠标放入BActivity上面 点击右键 选择ListObject
选择withoutgoing 查看BActivity 被谁引用
右键 选择GcRoot 选择exclude all..... 排除掉软引用
虚引用等等
此时 便可看到泄露的对象 是instance
内存快照对比 查找内存泄漏
按照上述方法 抓取一份mainActivity 的内存快照 和上述 打开BActivity 之后 有些泄露的快照进行对比
选择和泄露之后的mat 进行对比 添加过滤条件,用包名过滤 可以发现泄露之前的和泄露之后的少了3个文件,便可以知道 是因为是因为单例模式 context
持有了BActivity的引用导致的内存泄漏
全局查看泄露情况
从MainActivity 打开BActivity 然后再关闭BActivity
执行以下命令
adb shell dumpsys meminfo com.demo -d
此时界面在MainActivity,可以看到还存在两个Activity 证明 BActivity有泄露