Android:一般什么情况会导致内存泄漏?

最近在和小伙伴一起维护一个github项目,https://github.com/Moosphan/Android-Daily-Interview。
每天出一道面试题。感兴趣的可以点进去看看。最近要开始整理答案。所以顺手也在这里发布下自己写的相关面试题的答案。

正文开始

什么是内存泄漏

之前看大家的回答,好多把内存泄漏和内存溢出的概念搞混的。我这里简单解释下。Android给每个app分配了一定的内存(有人说谷歌给每个app的默认值是16MB,国内厂商都会对这个值进行改变,想想自己的app显示运行内存200多M,好心虚。)。内存溢出就是,你需要的内存超过了Android系统给每个app分配的内存,也就我们平时说得oom。说得官方一点就是:如果没有足够的内存完成实例,并且也无法再扩展,将会抛出oom。

再说内存溢出。这里用之前答案里的一句话,我觉得很精辟:

无非是生命周期长的对象持有生命周期短的对象的引用,造成生命周期短的对象使用完之后无法释放内存

其实这句话总结的已经很到位了。有一部分人应该知道jvm的回收算法主要是使用标记计数法,和可达性分析。不太清楚的可以看这里:垃圾回收算法,其中老年代主要用标记算法,新生代主要用可达性分析。那么一个对象,生命周期已经结束,但是因为被另一个对象引用,这样可达性分析就会判断这个对象不能被回收,那这个对象在内存中所占有的内存自然也无法释放,这就造成了我们说得内存泄漏。

什么情况造成内存泄漏

  • 资源未关闭(cursor,io流等)
  • 广播注册后没有反注册
  • Handler发消息(特别是延迟消息),消息没有消费掉,且没有remove。
  • 静态变量赋值了生命周期短的对象。比如工具类持有Context对象,设置为某个Activity。
  • 单例模式持有activity
  • 非静态内部类,持有父类引用,造成父类无法回收

内存泄漏会造成什么后果

  • 内存资源的浪费
  • 可能会oom
  • 卡顿(不是说泄漏就一定会卡顿,但是大量的泄漏一定会造成卡顿,特别是IO操作)
  • 频繁的GC

如何避免内存泄漏

  • 良好的编码习惯,有创建就有销毁,有add就有remove,有注册就有反注册,有绑定就有解绑。一定要成对出现。
  • 工具类中使用applicationContext
  • try catch 要加finally,对资源进行释放
  • 合理使用强,弱,软,虚引用。
  • 使用LeakCannery检查

你可能感兴趣的:(Android)