一些内存泄漏的场景:
1 非静态内部类的静态实例
2 多线程相关的匿名内部类/非静态内部类
3 Handle内存泄漏
4 未正确使用 Context
5 静态View
6 WebView
7 资源对象未关闭
8 集合中对象没清理
9 Bitmap对象
10 监昕器未关闭
根据内存泄漏场景1,写一个内存泄漏的Activity:
public class MemoryTestActivity extends AppCompatActivity {
static Inter mInter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memory_test);
mInter = new Inter();
}
class Inter{
}
}
运行app,使用AndroidStudio(v4.0.2)的profiler工具进行分析:
打开这个MemoryTestActivity,然后finish,使用AndroidStudio底部的profiler工具查看app运行状态,如下图:
0.png
点击MEMORY
1.png
点击 Dump Java heap,会生成下面的堆信息(手动选中下图的1,2处)
2.png
从上图可以看到MemoryTestActivity有内存泄漏,泄漏内存272字节。
这里的代码比较简单,是主动写的一个泄漏情景来测试用的,在实际开发中,可能即使找到了内存泄漏的Activity,也并不容易分析出内存泄露的原因,就需要使用MAT工具对这个HeapDump数据进行分析
使用MAT工具分析这个 HeapDump 数据
1 保存 HeapDump 数据
在上图标记3处,右键-->Export...-->保存到电脑中,命名为a.hprof
2 使用hprof-conv工具转换数据格式
hprof-conv是androidSDK中的一个工具,在platform-tools目录中:$(SDK_HOME)\platform-tools\hprof-conv.exe,使用CMD命令:
E:\temp>hprof-conv -z a.hprof a-mat.hprof
3 使用 MemoryAnalyzer (MAT) 分析a-mat.hprof
打开MemoryAnalyzer,点击左上角File-->Open Heap Dump...,打开a-mat.hprof
3.png
点击Histogram,查看柱状图,在Class name下面输入MemoryTestActivity,回车,进行过滤,可以看到内存泄漏的Activity
(也可以使用上面的OQL进行查询)
4.png
在MemoryTestActivity(标记2处)上右键-->Merge Shortest ... -->exclude all ... ,进入merge_shortest_paths视图
5.png
在上面的上图中,可以看到mInter的引用,由于mInter是静态的,所以MemoryTestActivity退出后不会销毁,而这个Inter类是非静态内部类,会持有MemoryTestActivity的引用,所以MemoryTestActivity不会被回收。
网友评论