Android内存泄露:是指进程中某些对象已经没有使用价值,但是它们却可以直接或间接的引用到gc roots导致无法被GC回收。
无用的对象占据着内存空间,使得实际可使用的内存变小,形象的说就是内存泄露了。
造成内存泄露的原因:
- 类的静态变量持有大数据对象
静态变量长期维持到大数据对象的引用,阻止垃圾回收。 - 非静态内部类的静态实例
非静态内部类会维持一个到外部类实例的引用,如果非静态内部类的实例是静态的,就会间接长期维持着外部类的引用,阻止被回收掉。 - 资源对象未关闭
资源性对象如Cursor、File、Socket,应该在使用后及时关闭。未在finally中关闭,会导致异常情况下资源对象未被释放的隐患。 - 注册对象未反注册
未反注册会导致观察者列表里维持着对象的引用,阻止垃圾回收。 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
代替。