Android Memory Leaks
前一阵子,有一个bug是关于monkey测试到的memoryleak,优先级是veryhigh。负责解这个bug的同事分析了好几天,最后好像也没有解决。我一开始对如何查找memoryleak也是非常模糊,总感觉无处下手。正好今天看到官方的一篇文章(avoiding-memory-leaks)来分析这个问题。
从文章角度看来,android的ml是有它自身的特点的:大量的context引用。我们知道,context是android很基础的类之一,有众多必须的api。于是引用来引用去,万一把某个context间接引用到static变量上去了,那不就有泄漏的危险了么。文章的那个例子就是说明这一点。
同时,主贴给出了4点以回避context相关的泄漏:
Insummary,toavoidcontext-relatedmemoryleaks,rememberthefollowing:
- Donotkeeplong-livedreferencestoacontext-activity(areferencetoanactivityshouldhavethesamelifecycleastheactivityitself)
- Tryusingthecontext-applicationinsteadofacontext-activity
- Avoidnon-staticinnerclassesinanactivityifyoudon'tcontroltheirlifecycle,useastaticinnerclassandmakeaweakreferencetotheactivityinside.ThesolutiontothisissueistouseastaticinnerclasswithaWeakReferencetotheouterclass,asdoneinViewRootanditsWinnerclassforinstance
- Agarbagecollectorisnotaninsuranceagainstmemoryleaks
我自己琢磨出下面有关或者无关的几点:
1.从4点解决思路可以看出,文章强调对代码的控制,有些时候gc机制给程序员带来的负面影响就是容易忽视对代码生命周期的管理,尤其销毁(destroy)。至少我在看到这篇文章,给我很大启示。我想出现这种情况的原因,是因为java程序员对自身职责和语言职责界定不清楚导致,什么应该让语言本身去解决(如gc机制),什么应该程序员自己来。另一点是java程序员可能缺乏对控制语言的欲望,因为框架、标准库api实在太多了,熟悉api还来不及呢,更别说花更多的精力去探究api的设计意图和实现。要改变这种思维,只有慢慢地练,拿我自己来说,我现在开始督促自己多问为什么,多去追究设计者的意图,多从设计者的高度去体会这个api和体系结构,现在已经有了一些收获。
2.尽量applicationcontext是因为一个apk只有一个applicationcontext,但是经常会有多个activitycontext,尤其activity来回切换时,很容易出现某些activitycontext被间接引用而不能释放
3.过份依赖gc会死的很惨
4.只会点java不行,至少得了解c这样强控制类的语言的机制,要不等到出了这类问题,可能没有解决问题的思路。习惯了一种语言,可能就习惯了它的某些缺点,让你容易忽视背后的风险。