![](https://img.haomeiwen.com/i8207483/65a8395aeac51537.jpg)
在帝国设计中,处处都隐藏着这样那样的风险,稍有设计不当,帝国可能随时可能崩塌。
![](https://img.haomeiwen.com/i8207483/e8a6b1f63d161d7a.jpg)
生态平台(领主)为每个帝国都提供了定期的垃圾回收服务,帝国的贸易和生活所产生的垃圾都会被定期回收,来保证帝国正常的运转。回收哪些垃圾是根据一定条件来判断是否将不再作用的(使用的)对象进行垃圾回收,但是,如果设计存在问题,可能导致一些活动所产生的垃圾一直无法回收,这样下去是必垃圾遍地,很可能会导致帝国的崩塌。
![](https://img.haomeiwen.com/i8207483/7062f814c4475b67.jpg)
发生以上情况可能是由内存泄露所引起的。那么我们先说一说什么是内存泄露吧。
我们帝国的交易在市场频繁地进行,多数交易并不是独立,而是相互关联的,例如我们购买汽车,汽车制造商对于跟制造轮子的企业进行交易。这是链式交易或是树形交易,一旦交易完成,其相关交易也必将消失。但是由于某种设计不当,可能造成有一些本应该消失的交易还在市场占有一席之地,这样就会多少影响帝国贸易,让新的交易无法进入市场,最终导致帝国崩塌。
![](https://img.haomeiwen.com/i8207483/a49eac62c53ba4e4.jpeg)
内存泄露就是一些不再被使用的对象,由于被另一个存活的对象引用着,造成垃圾回收无法对其进行处理,导致其长驻内存。
由于 Activity 和其包含的 View 都存在强引用的关系,所以特别容易造成内存泄露。
Activity(都市)除了我们主动销毁他,还有两种情况他可能会在内存中被销毁后重建。
1. 当手机在横屏和竖屏间切换时
2. 当由于内存紧张,Activity 没有处于前端也会被自动销毁。
一旦 Activity 没有被销毁而长驻内存,他就是消耗资源的空城,这样吃空头的都市是必会耗尽帝国资源,所以我们一定一定要防止 Activity 的泄漏,这段话应该加粗加黑。
当实例化一个对象需要 context,我们切记不要用 Activity 作为 context。应该选择 Application 作为 context 传入构造函数。
如果我们定义一个 TextView
如果你将 View 定义为 static 由于 static 位于堆内存呢,如果你不将赋值null。
![](https://img.haomeiwen.com/i8207483/1bbaeae7db8041f9.png)
由于他是 Activity 的静态的属性,所以Activity 也不会在垃圾回收中被回收。这样如果有图片作为背景,看一看 TextView > Activity > window 这样。帝国就一步一步走向崩塌。
静态字段非常危险,可能会关联 Activity 以及一些其他的对象。大部分内存问题都是可能是由此引起的。代码中定义一个静态 View,这个 View 就会引起 Activity 的泄露。
分析一下原因,当 Activity.setContentView() 方法时,布局中的每一个 View 在实例化都会将 Activity 的 Context 作为引用(作为 View 的构造函数)来创建一个实例。如果发生这种情况,我们就需要及时在 view 不再使用时,将其赋值为 null 来垃圾回收这个对象。我们在此基础上,再更近一层。
![](https://img.haomeiwen.com/i8207483/989aead12e548901.png)
解决方案—我们需要在 onStop 和 onDestroy 回调函数中,将 View 赋值为 null。这里提一下尽量在 onStop 进行处理,这样更安全。有关为什么尽量在 onStop 而不是 onDestroy 处理,请见《都市的轮回》。但是这个解决方案,并不完美,他可能导致 NullPointerException 因为设置为 null 可能在下一次实例化不当。
所以终极解决方案就是—避免使用静态类。
待续
网友评论