Android Profiler工具和mat进行内存泄漏分析
我们就需要使用mat进行分析,打开以后如下图,
image.png
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,点击某一时刻,可以查看堆内存里面存在的对象
image.png
打开BActivity 后 再关闭,此时抓取内存快照,然后导出
image.png
这时候会生成一个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
image.png
- Histogram可以列出内存中的对象,对象的个数以及大小。
- Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。
- Top consumers通过图形列出最大的object。
- Leak Suspects通过MA自动分析泄漏的原因。
点击Histogram
image.png可以看到BActivity 自身有288(Shallow Heap)大小,引用其他的对象大于4416(Retained Heap)
将鼠标放入BActivity上面 点击右键 选择ListObject
image.png
选择withoutgoing 查看BActivity 被谁引用
image.png右键 选择GcRoot 选择exclude all..... 排除掉软引用
虚引用等等
此时 便可看到泄露的对象 是instance
image.png
内存快照对比 查找内存泄漏
按照上述方法 抓取一份mainActivity 的内存快照 和上述 打开BActivity 之后 有些泄露的快照进行对比
image.png image.png
选择和泄露之后的mat 进行对比 添加过滤条件,用包名过滤 可以发现泄露之前的和泄露之后的少了3个文件,便可以知道 是因为是因为单例模式 context
持有了BActivity的引用导致的内存泄漏
全局查看泄露情况
从MainActivity 打开BActivity 然后再关闭BActivity
执行以下命令
adb shell dumpsys meminfo com.demo -d
此时界面在MainActivity,可以看到还存在两个Activity 证明 BActivity有泄露