内存泄露

什么是内存泄露

内存泄漏的发生原因本质上是因为生命周期较长的对象去引用生命周期较短的对象,导致生命周期短的对象无法被GC及时回收掉,从而导致被占用的内存无法被释放,如果程序长期运行最终可能会导致OOM内存溢出。

什么情况下容易发生内存泄漏?

导致内存泄漏的原因有很多以下列举几种常见情况。

一、Handler 引起的内存泄漏。

我们知道,Handler、Message、MessageQueue是相互关联在一起的,Handler通过发送消息Message与主线程进行交互,如果Handler发送的消息Message尚未被处理,该Message及发送它的Handler对象将被MessageQueue一直持有,这样就可能会导致Handler无法被回收,从而导致内存泄漏。

举个例子:

AActivity代码中有一个延迟1秒执行的消息Message,当界面从AActivity跳转到BActivity时,AActivity自动进入后台,此时如果系统资源紧张(或者打开设置里面的“不保留活动”选项),AActivity将会被finish。但问题来了,假设AActivity的Handler对象mHandler为非静态匿名内部类对象,它会自动持有外部类AActivity的引用,从而导致SecondActivity无法被回收,造成内存泄漏。

解决办法:

将Handler声明为静态内部类,就不会持有外部类SecondActivity的引用,其生命周期就和外部类无关,如果Handler里面需要context的话,可以通过弱引用方式引用外部类,或者直接在Activity的onDestroy中将Handler对象销毁。

二、Bitmap没有调用recycle()

Bitmap对象在确认不使用时,我们应该先调用recycle()释放内存,然后在设置为null,否则会导致内存泄漏。

解决办法:

在Acrivity或Fragment处调用recycle()。

三、集合中对象没有清理造成的内存泄漏

我们经常把一些对象的引用加入到集合中,但我们不需要改对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大。如果这个集合是static,就会导致集合内的资源一直占用内存无法被清理。

解决办法:

当集合资源无用之后将其置空。

四、资源对象没关闭造成的内存泄漏

资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我们在不使用的时候,应该及时关闭它们,以便它们的缓冲及时回收内存。而不是等待GC来处理。

五、注册没有取消造成的内存泄漏

这种Android内存泄漏比Java的内存泄漏还要严重,因为其他一些Android程序可能引用系统的Android程序的对象(如注册机制)。即使Android程序已经结束,但是别的应用程序仍然还有对Android程序的某个对象的引用,也会造成内存泄漏。

解决方法:

1.使用ApplicationContext代替ActivityContext;
2.在Activity执行onDestory时,调用反注册;

检测内存泄漏的方法


LeakCanary 工具

官方地址如下:https://github.com/square/leakcanary/LeakCanary需要在项目代码中集成。当内存泄漏发生时,LeakCanary 会弹窗提示并生成对应的堆存储信息记录。

Android Profiler分析器

打开Android Studio,编译代码,在模拟器或者真机上运行App,然后点击以下图标,进入如下界面

该方式可以直观的观察在程序运行期间产生的内存波动并且可以明确列出所有产生内存消耗的对象以及内存分配情况,需要一些经验才能有效使用,

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaowang_lj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值