Andoid - 内存泄漏

什么是内存泄漏?

android 内存泄漏是指进程中的某些对象(垃圾对象)已经不再使用,但是他们仍然可以直接或间接的引用到GC roots 导致无法被GC回收。无用的对象占据着内存空间,使得实际可用的内存变小,形象的说法就是内存泄露了。

GC的跟搜索算法

Android 虚拟机的垃圾回收采用的是根搜索算法。GC会从根节点(GC Roots,GC会选择一些它了解还存活的对象作为内存遍历的根节点,比方说thread stack中的变量,JNI中的全局变量,zygote中的对象(class loader加载)等)开始对heap进行遍历,部分没有直接或间接引用到GC Roots 的就是需要回收的垃圾,会被GC回收。

主要发生场景

  • Activity使用静态成员。   静态变量长期维持对大数据对象的引用,阻止垃圾回收。
  • 资源对象未及时关闭。  资源性对象如Cursor、File、Socket,应该在使用后及时关闭。未在finallay中关闭,会导致异常情况下资源对象未被释放的风险。
  • Handler临时性内存泄漏。   Handler通过发送Message与主线程交互,Message发出之后是存储在MessageQueue中的,有些Message 也不是马上就被处理的。在Message中存在一个成员变量target,是对handler的强引用,如果Message在Queue中存在的时间越长,就容易导致handler无法被回收。如果handler是非静态的,则会导致Activity或Service不会被回收。AsyncTask内部也是handler机制,同样存在内存泄漏的风险。这种内存泄漏一般是临时性的。
  • 非静态内部类的静态实例。
    非静态内部类会维持一个到外部类实例的引用,如果非静态内部类的实例是静态的,就会间接长期维持着外部类的引用,阻止被回收掉。
  • 注册对象未反注册。 未反注册会导致观察者列表里维持着对象的引用,阻止垃圾回收。常见的有注册广播接收器,注册观察者等。

预防

  • 不要维持到Activity的长久引用,一个activity的引用的生存周期应该和activity的生命周期相同。
  • 尽量使用context-application代替context-activity
  • Activity中尽量不要使用非静态内部类,可以使用静态内部类和WeakReference代替。

转载于:https://my.oschina.net/kians/blog/1248108

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值