Skip to content

Commit

Permalink
Update 第03期-什么情况下会导致内存泄漏问题.md
Browse files Browse the repository at this point in the history
  • Loading branch information
MoJieBlog authored Aug 13, 2019
1 parent 91b53f9 commit e4cadba
Showing 1 changed file with 37 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,42 @@

> [**什么情况下会导致内存泄漏问题?**](https://github.com/Moosphan/Android-Daily-Interview/issues/3)
下面从几个方面说明这个问题
* 什么是内存泄漏
* 什么情况造成内存泄漏
* 内存泄漏会造成什么后果
* 如何避免内存泄漏

正文开始

#### 什么是内存泄漏

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

再说内存溢出。这里用之前答案里的一句话,我觉得很精辟:
> 无非是生命周期长的对象持有生命周期短的对象的引用,造成生命周期短的对象使用完之后无法释放内存
其实这句话总结的已经很到位了。有一部分人应该知道jvm的回收算法主要是使用标记计数法,和可达性分析。不太清楚的可以看[这里:垃圾回收算法](https://github.com/MoJieBlog/JVM-study/blob/master/垃圾回收.md),其中老年代主要用标记算法,新生代主要用可达性分析。那么一个对象,生命周期已经结束,但是因为被另一个对象引用,这样可达性分析就会判断这个对象不能被回收,那这个对象在内存中所占有的内存自然也无法释放,这就造成了我们说得内存泄漏。
#### 什么情况造成内存泄漏
* 资源未关闭(cursor,io流等)
* 广播注册后没有反注册
* Handler发消息(特别是延迟消息),消息没有消费掉,且没有remove。
* 静态变量赋值了生命周期短的对象。比如工具类持有Context对象,设置为某个Activity。
* 单例模式持有activity
* 非静态内部类,持有父类引用,造成父类无法回收
*


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

#### 如何避免内存泄漏

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

0 comments on commit e4cadba

Please sign in to comment.