内存泄漏排查方法

2. 内存泄漏

2.1 点击Android studio 中 Profiler image.png 这样的一个图标

打开后,运行程序,点击 record , 反复进去目标 Activity ,点击强制 GC 最后点击 stop :

image.png

然后点击 Arrange by package :

image.png

找到自己的应用包名:

image.png

点击 image.png

类似这样的图标,dump hprof 文件 。

我用idea 开发工具打开后:

image.png

点击右上角那个运行按钮,出现以下:

image.png

然后继续点开 Leaked Activities 选项 :

image.png

这样我们就知道是 LeakActivity 发生了 泄漏 ,那如何去找到泄漏的原因需要使用 MAT 工具;

以上是检测泄漏 Activity 的方式之一,通常我也会在做这个之前,做一个小的判断,通过 adb 命令,判断内存情况,同样也是反复进出 目标Activity , 然后打印内存信息。

1
adb shell dumpsys meminfo "packageName| pid"

image.png

观察 Activities 的数量,反复进出目标Activity , 如果 Activities 只增加而不减少,那么目标 Activity 基本上就发生内存泄漏了。

2.2 MAT

借助 sdk 里 platform-tools 中的 hprof-conv.exe 进行hprof 文件转化,转化命令为:

1
2
//示例
hprof-conv -z test.hprof test1.hprof

文件名我就叫 test , 转化后为 test1.hprof , 转化后的文件用 Mat 工具打开:

image.png

然后点击左上角的这个按钮:

image.png

然后在显示的 Historgram 中输入之前泄漏的 Activity :

image.png

将搜索到的结果,右键,去除 软引用,弱引用,虚引用的对象:

image.png

筛选得出结果:

image.png

发现 LeakActivity 被这个 callback –MyRunnable 引用,发现原因进一步就可以解决了。

泄漏的LeakActivity.java 的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class LeakActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_leak1);

handler.postDelayed(new MyRunnable(),10000);
}

private Handler handler = new Handler();

class MyRunnable implements Runnable{

@Override
public void run() {
Log.i("qq >>>","test");
}
}
}
-------------本文结束感谢您的阅读-------------