关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。
一、导读
我们继续总结学习Android 基础知识,温故知新。
二、概览
内存泄漏(Memory leak)是指程序在运行过程中分配的内存资源没有被正确释放,导致这部分内存无法再被程序使用,最终消耗了系统的可用内存。
内存泄漏可能会导致以下问题:
- 内存耗尽:内存泄漏会导致程序占用的内存越来越多,最终导致系统可用内存耗尽,使程序无法继续运行。
- 性能下降:由于内存泄漏的存在,系统中的可用内存减少,导致系统的性能下降,运行速度变慢。
- 程序崩溃:当内存泄漏严重时,系统无法分配到足够的内存来执行程序,导致程序崩溃或者无法启动。
内存泄漏的原因可能包括:
- 错误的内存分配和释放:程序中可能存在分配内存后未正确释放的情况,导致内存泄漏。
- 对象引用未释放:当一个对象的引用无法被正常释放时,其中包含的内存也无法被回收,导致内存泄漏。
- 循环引用:两个或多个对象之间互相引用,且没有被其他引用指向时,可能导致内存泄漏。
- 缓存未清理:缓存或临时存储的数据长时间保留在内存中,没有及时清理,可能导致内存泄漏。
在开发过程中,可以使用内存分析工具来检测和解决内存泄漏问题,如内存检测工具、代码审查等。
三、案例分析
不同的工具有不同的使用场景,对应线下场景,我们先用 android studio自带的工具,
我们捕获堆转储文件分析
3.1 使用 memory-profiler
//匿名内部类
private Handler mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg){
super.handleMessage(msg);
}
}
我们先说下原因,匿名内部类默认持有外部类的引用,如果这个mHandler有个延时任务未执行,此时退出activity页面,
此时Handler又持有Activity的引用,导致GC无法回收Activity,导致内存泄漏。
我们大致看下引用链,也能看到泄漏的地方
3.2 使用MAT(Memory Analyzer)
将上面的堆转储另存为 HPROF 文件,再用mat打开
hprof-conv heap-original.hprof heap-converted.hprof
打开后预览页面是这样的,
3.2.1 通过OQL语法
我们直接通过OQL语法来排查内存泄漏,如上图箭头所示的地方,我们在oql页面输入下面的查询代码,然后按下图中红色的小箭头,
select * from instanceof android.app.Activity
会在下面出现查询结果,如下图所示,可以看到,查询到了9个一样的 MemoryShakeActivity,这肯定是有问题的 ,
那我们如何确认是哪里有问题呢?
我们在其中一个activity上右键点击,然后会出现一个菜单,选择 path to gc root, 再选择最长的那个选项 exclude all ...
最终,我们在mat里面会出现一个新的页面,也就找到了内存泄漏的地方,看下图:
3.2.2 通过 Histogram(直方图)
它可以列出任意一个类的实例数(每个对象的统计)。它支持使用正则表达式来查找某个特定的类,还可以计算出该类所有对象的保留堆最小值或者精确值,
我们可以通过正则表达式输入 MemoryShakeActivity, 看到Histogram列出了与 MemoryShakeActivity 相关的类
然后选中一行,然后依次选择,点击右键 -> Merge Shortest Paths to GC Roots -> exclude all phantom/weak/soft etc.references(排查虚引用/弱引用/软引用等)
然后我们就可以看到哪里泄漏了
Merge Shortest Paths to GC Roots 可以查看一个对象到RC Roots是否存在引用链相连接,
在JAVA中是通过可达性(Reachability Analysis)来判断对象是否存活,这个算法的基本思想是通过一系列的称谓"GC Roots"的对象作为起始点,
从这些节点开始向下搜索,搜索所走得路径称为引用链,当一个对象到GC Roots没有任何引用链相连则该对象被判定为可以被回收的对象,反之不能被回收,
虚引用/弱引用/软引用的对象可以直接被GC给回收.
3.2.3 通过 Dominator Tree(支配树)
Dominator Tree(支配树)提供了程序中最占内存的对象的排列。
使用方法跟Histogram(直方图)差不多,按照上面类似的操作即可。
3.2.4 通过 leak suspects (泄露疑点)
如下图
四、 推荐阅读
[SQL 专栏]
[数据结构与算法]
[Android学习专栏]