内存分析工具android studio,使用AndroidStudio提供的Android Profiler工具和mat进行内存泄漏分析...

废话不多说直接说流程

给项目中集成LeakCanary工具进行内存泄漏检测。发现有内存泄漏后该工具会进行提示

有内存泄露后我们需要使用as的profiler工具进行分析并获取到.hprof文件,步骤如下

直接上图

点击如下按钮打开profiler工具

image.png

打开以后如下图,

3571184-f5ba2fc11268fc54.png

我们选择MEMORY,进去以后如下图

image.png

然后我们对有内存泄漏的页面进行反复操作(为了模拟泄漏场景)。然后点击下图1位置的垃圾桶进行强制gc,再点击2的位置获取堆栈信息

image.png

当堆栈信息获取完成后,会弹出如下框,我们将排序方式选为 Arrange by package(好定位我们自己的代码),找到我们的代码后我们真的发现,应该已经被回收了的LoginActivity还占用这内存。但是为什么没有被销毁,还有那些对象引用着他。这时我们就需要点击位置为3的地方,导出.hprof文件进行具体分析了

image.png

导出以后我们会得到1.hprof文件,但是这个不是mat工具用到的标准文件。我们需要使用sdk自带的hprof-conv.exe(platform-tools文件夹下) 工具进行转换,转换以后我们就得到了1_mat.hprof文件

转换mat标准文件

命令:hprof-conv -z src dst

例如:hprof-conv -z 1.hprof 1_mat.hprof

下来我们就需要使用mat进行分析了,打开以后如下图,我们呢点击histogram

mat下载地址:http://www.eclipse.org/mat/downloads.php

image.png

进入Histogram 页面有我们在红框位置输入我们想要找的类,然后右键选择merge shortest paths to Gc roots然后在选择exclude all phantom/weak/soft etc.references选项

image.png

就得到了如下的引用图,从图中我们分析出 loginActivity是被inputMethodManager所引用(这其实是android系统的一个bug),所以我们主要将两者之间的联系给断开就行,解决方法如下

image.png

使用反射的方式将引用的view置为null

InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

try {

//获得 所有属性 getField->public 以及父类

Field mCurRootViewField = InputMethodManager.class.getDeclaredField("mCurRootView");

//设置允许访问权限

mCurRootViewField.setAccessible(true);

// 对象

Object mCurRootView = mCurRootViewField.get(im);

if (null != mCurRootView){

Context context = ((View) mCurRootView).getContext();

if (context == this){

//破怪gc 引用链

mCurRootViewField.set(im,null);

}

}

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

你可能感兴趣的:(内存分析工具android,studio)