当前位置: 首页 > 编程笔记 >

Android中Memory Leak原因分析及解决办法

荀金鹏
2023-03-14
本文向大家介绍Android中Memory Leak原因分析及解决办法,包括了Android中Memory Leak原因分析及解决办法的使用技巧和注意事项,需要的朋友参考一下

在Android开发过程中,我们经常碰到的情况就是在我们不清楚为什么情况下,程序突然出现Crash了。其中有一类日志相信大家都经常碰到过,这类日志就是OOM相关的日志。这类日志除了我们知道的Bitmap操作的时候会经常导致,还有一种隐藏的较深的原因就是内存泄露(Memory Leak)。

内存泄露产生原因和影响: 原因:当一个Object不再需要的时候,本该被GC回收时,但是因为另一个正在使用的Object持有它导致不能正常的被回收,本该被回收的对象不能回收,还存留在堆内存中,此时就产生了内存泄露。影响:Android系统能够为每个应用程序分配的内存是有限的,当一个应用程序中产生的内存泄露过多的时候,会难免导致应用程序需要的内存超过限额而导致内存溢出使得应用程序崩溃。 内存泄露的检测方式

推荐使用 LeakCanary 工具来检测应用程序是否存在内存泄露。LeakCanary是由 Square 开源的一款轻量级的第三方内存泄漏检测工具,当检测到程序中产生内存泄漏时,它将以最直观的方式告诉我们哪里产生了内存泄漏和导致谁泄漏了而不能被回收。

如何避免内存泄露

1、合理使用单例模式。

单例的静态特性使得其生命周期和应用的生命周期一样长。

如图,我们先声明一个单例对象:


然后在Activity使用的时候,习惯性的传一个this:


集成了LeakCanary后测试,发现内存泄露了:


解决方案:

一般情况下,改成如下图的写法就可以了,因为单例的生命周期和应用的一样长,这样就防止了内存泄漏。:


总结:单例模式造成泄漏的原因是拥有更长生命周期的对象持有短生命周期对象的强引用。

2、使用资源时注意资源的关闭

一般情况下,容易产生内存泄露的资源主要为:File,Cursor,Stream,Bitmap,BroadcastReceiver等,这些资源在使用时建议及时关闭,否则当这些资源没有及时回收的时候,内存泄露也就产生了。针对这些资源使用,给如下建议:

BroadcastReceiver 在register之后,需要在适当的时机unregister Cursor、Stream、File 这类资源类型的对象往往会使用一些Cache,所以我们在不使用的时候,应该及时关闭,以便Cache被及时回收。如果我们仅仅把它的引用设置为null,而不去关闭他们,往往会造成内存泄露。一般建议是先close()后置为null。 Bitmap在不使用的时候,调用recycle()方法。目前 Android 2.3版本以后,不需要我们手动去这样做的,这里也就是简单的交代一下。

3、 合理使用Handler避免内存泄露

在我们使用Handler的时候,经常看到编辑器提示我们Handler可能会造成内存泄露,一般在这种情况下,我们可以将Handler独立出来或者使用静态内部类,这样可以避免内存泄露。
这样做的原因是:非静态内部类会潜在的持有它所属的外部类的引用,但是静态内部类是不会的。

4、 合理的使用WeakReference来引用外部类的成员变量

我们可以使用WeakReference来规避好多潜在的内存泄露的问题,但是并不表明WeakReference就是解决内存泄露的金钥匙。是否使用WeakReference主要取决于对当前对问题的理解,这需要我们对问题的的建模思想。

 类似资料:
  • 本文向大家介绍Android 关于“NetworkOnMainThreadException”问题的原因分析及解决办法,包括了Android 关于“NetworkOnMainThreadException”问题的原因分析及解决办法的使用技巧和注意事项,需要的朋友参考一下 网络收集的原因如下,以及解决办法: 我补充总结一下: 解决办法一: 在操作网络类(socket连接)的activity的prot

  • 本文向大家介绍JavaScript中的ParseInt("08")和“09”返回0的原因分析及解决办法,包括了JavaScript中的ParseInt("08")和“09”返回0的原因分析及解决办法的使用技巧和注意事项,需要的朋友参考一下 今天在程序中出现一个bugger ,调试了好久,最后才发现,原来是这个问题。 做了一个实验: alert(parseInt("01")),当这个里面的值为01=

  • 本文向大家介绍java 出现NullPointerException的原因及解决办法,包括了java 出现NullPointerException的原因及解决办法的使用技巧和注意事项,需要的朋友参考一下 java 出现NullPointerException的原因及解决办法 日常开发过程中,最常见的异常莫过于NullPointerException,之前的时候,只是知道去找到报错的位置,然后去解决

  • 本文向大家介绍PHP中ID设置自增后不连续的原因分析及解决办法,包括了PHP中ID设置自增后不连续的原因分析及解决办法的使用技巧和注意事项,需要的朋友参考一下 PHP中ID设置自增后不连续的原因分析如下所述: 每次删除把这两行家伙加上就行了 还有就是这个 使用mysqli对象中的query()方法每次调用只能执行一条SQL命令。 如果需要一次执行多条SQL命令,就必须使用mysqli对象中的 mu

  • 本文向大家介绍Oracle用户被锁的原因及解决办法,包括了Oracle用户被锁的原因及解决办法的使用技巧和注意事项,需要的朋友参考一下 在登陆时被告知test用户被锁 1、用dba角色的用户登陆,进行解锁,先设置具体时间格式,以便查看具体时间 2、查看具体的被锁时间 3、解锁 4、查看是那个ip造成的test用户被锁 查看$ORACLE_HOME/network/admin/log/listene

  • 本文向大家介绍Jquery Ajax请求文件下载操作失败的原因分析及解决办法,包括了Jquery Ajax请求文件下载操作失败的原因分析及解决办法的使用技巧和注意事项,需要的朋友参考一下 jQuery确实是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯。 废话少说,直接进入正题,我们先来分析一下失败的原因 一、失败的原因 那是因为