LeakC anary傻瓜式的内存泄露检测工具
在Andr oid开发过程中如果需要处理图片或者大量数据的时候常常会遇到OOM(java. lang.OutOf Memor yErro r),一般出现最多的是在创建Bitm ap上也有可能是在内存中处理了大量的数据造成。
一般会针对Bitam p做下面几种的优化:
1.增加进程的内存
2.使用Bit map.Confi g.ALPHA_8(图片失真)
3.显示的调用Syste m.gc()
4. catch Excep tion
5.调用bit map.recyc le()
6.缩小bitmap的大小(如果是读取的原图是一个大图应该先采用这种方式 Bitma p如果是刚好适配屏幕的就不需要缩小了)
7.使用弱引用和软引用(googl e已经不建议使用了,Andro id的GC效率非常高只要保证对象没有被引用即可)
但是我们会忽略掉一个问题就是什么造成了OOM?一般都发生OOM崩溃的地方都不一定是内存泄露的地方崩溃了的原因可能Ac tivit y造成的内存泄露也可能是操作数据库造成的内存泄露 当内存已经非常接近峰值的时候这个时候恰巧要创建一个Bitm ap对象就会发生OO M(Bitma p对象占用的内存空间比较大) 。
内存泄露
每个对象都有自己的生命周期Activ ity会调用onDe stroy做销毁处理但是如果使用Acti vity的Conte xt调用T oast,就会把这个Activ ity的引用传给了T oast,而Toas t的生命周期不会随着Activ ity的销毁而销毁,这样就造成了Acti vity的内存泄露 因为它被T oast引用着。
常见的内存泄露形成的原因:
1. Toast持有Act ivity的引用
2.数据库游标Curso r没有关闭
3. Adapt er没有复用conv ertVi ew
4.对象被生命周期更长的对象引用 Activ ity被静态集合引用
. . . .
监控内存的方式
Heap Dump是一种Jav a比较常用的检测内存的方式简单来说就是我们在一个初始状态A Dump一次内存在做了一些操作之后回到状态A再Dump一次内存。
对两次Du np的内存数据(hprof )使用分析工具做分析(MAT) ,根据分析的结果就能知道是否存在内存泄露这种方式比较复杂和繁琐并不是特别易用。
Moito rs:Andro idSDK 自带的内存监控工具Monit ors能看到内存的变化内存是增加还是减少.打开一个A ctivi ty会导致内存增加关闭一个A ctivi ty会导致内存减少反复的实验如果每次打开一个Ac tivit y再关闭之后增加的内存不会减少就说明这个Activ ity有内存泄露的问题可以使用l og辅助进行检测这种方式的缺点是并不是特别的准确 因为内存的释放和对象的生命周期有关也和GC的调用有关。
而Leak Canar y就是一个简单的方便的内存检测工具可以轻易的发现内存问题还会生成更加简单清晰的报告。
LeakC anary
LeakC anary是一个开源的检测内存泄露的ja va库。项目地址 https
://githu b.com/squar e/leakc anary
LeakC anary实际上就是在本机上自动做了He ap dump对生成的h prof文件进行分析展示结果。和手工分析Heap Dump的方式得到的结果是一样的。
下面是一个LeakC anary的结果截图
集成Lea kCana ry
在buil d.gradl e添加依赖depen denci es {debug Compi le 'com. squar eup. leakc anary :leakc anary -andro id:1.3. 1'relea seCom pile 'com. squar eup. leakc anary :leakc anary -andro id-no-op: 1.3. 1'testC ompil e 'com. squar eup. leakc anary :leakc anary -andro id-no-op: 1.3. 1'
}
使用Lea kCana ry会影响程序的性能尤其是在H eap dump和分析操作时不过我们可以在依赖里面指定对应的版本debug的时候才进行分析relea se的时候不进行分析。debug Compi le可以使用检测版本 com. squar eup. leakc anary :leakc anary -andro id relea seCom pile使用no-op模式 即No Opera tion Perfo rmed就是不会把对应的类库编译,指定类库为无用的指令:com. squar eup. leakc anary :leakc anary -andro id-no-op设置L eakCa nary为无用指令。
然后在Ap plica tion中加入分析A ctivi ty的代码
publi c class Examp leApp licat ion exten ds Appli catio n{
@Overr ide publi cvoid onCre ate() {super .onCre ate() ;
LeakC anary .insta ll(this) ;
}
}
这样就可以检测Act ivity的内存泄露了。 内部实现使用了Act ivity Lifec ycleC allba cks方法监控所有A ctivi ty的生命周期。
检测其他对象
LeakC anary中提供了R efWat cher类可, 以用来监控所有的对象。
首先需要实例化Ref Watch er:publi c stati c RefWa tcher sRefW atche r=LeakC anary .insta ll(mCont ext) ;
对于监控的对象使用sRefW atche r.watch (this)
一般我们是在对象销毁的时候对对象进行监控,比如内部实现的对于A ctivi ty的监控:priva tefinal Activ ityLi fecyc leCal lback slifec ycleC allba cks=newActiv ityLi fecyc leCal lback s() {publi c void onAct ivity Creat ed(Activ ity activ ity, Bundl esaved Insta nceSt ate) {
}publi cvoid onAct ivity Start ed(Activ ity activ ity) {
}
publi cvoid onAct ivity Resum ed(Activ ity activ ity) {
}publi cvoid onAct ivity Pause d(Activ ity activ ity) {
}publi cvoid onAct ivity Stopp ed(Activ ity activ ity) {
}publi c void onAct ivity SaveI nstan ceSta te(Activ ity activ ity,Bundl e outSt ate) {
}publi cvoid onAct ivity Destr oyed(Activ ity activ ity) {
Activ ityRe fWatc her. this.onAct ivity Destr oyed(activ ity) ;
}
} ;
只是在on Activ ityDe stroy ed的时候才对于ac tivit y进行了监控。
如何解决内存泄露
一般情况内存泄露的原因都是由于引用的使用不当造成的而且And roid的
GC能够保证回收循环引用(如果一个循环引用没有外部引用时就会被回收)而且And roid的GC效率很高当然GC的算法本身也在不停的改进。
一般情况下我们尽量避免错误的引用方式带来的内存泄露问题
1.生命周期长的对象引用生命周期短的对象 比如sta tic的对象群引用A ctivi ty
2.使用App licat ion的C ontex t对象而不是Ac tivit y的Con text
3.避免非静态类的内部类对于类的隐式引用使用静态的内部类
4.使用And roid的缓存机制 比如Lis tView的复用机制
5.手动关闭资源比如Cur ous的关闭
6. regis terRe ceive r和unR egist erRec eiver成对出现
SugarHosts 糖果主机商也算是比较老牌的主机商,从2009年开始推出虚拟主机以来,目前当然还是以虚拟主机为主,也有新增云服务器和独立服务器。早年很多网友也比较争议他们家是不是国人商家,其实这些不是特别重要,我们很多国人商家或者国外商家主要还是看重的是品质和服务。一晃十二年过去,有看到SugarHosts糖果主机商12周年的促销活动。如果我们有需要香港、美国、德国虚拟主机的可以选择,他们家的...
轻云互联成立于2018年的国人商家,广州轻云互联网络科技有限公司旗下品牌,主要从事VPS、虚拟主机等云计算产品业务,适合建站、新手上车的值得选择,香港三网直连(电信CN2GIA联通移动CN2直连);美国圣何塞(回程三网CN2GIA)线路,所有产品均采用KVM虚拟技术架构,高效售后保障,稳定多年,高性能可用,网络优质,为您的业务保驾护航。官方网站:点击进入广州轻云网络科技有限公司活动规则:1.用户购...
horain怎么样?horain cloud是一家2019年成立的国人主机商家,隶属于北京辰帆科技有限公司,horain持有增值电信业务经营许可证(B1-20203595),与中国电信天翼云、腾讯云、华为云、UCloud、AWS等签署渠道合作协议,主要提企业和个人提供云服务器,目前商家推出了几款特价物理机,都是在内地,性价比不错,其中有目前性能比较强悍的AMD+NVMe系列。点击进入:horain...