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成对出现
速云怎么样?速云,国人商家,提供广州移动、深圳移动、广州茂名联通、香港hkt等VDS和独立服务器。现在暑期限时特惠,力度大。广州移动/深圳移动/广东联通/香港HKT等9折优惠,最低月付9元;暑期特惠,带宽、流量翻倍,深港mplc免费试用!点击进入:速云官方网站地址速云优惠码:全场9折优惠码:summer速云优惠活动:活动期间,所有地区所有配置可享受9折优惠,深圳/广州地区流量计费VDS可选择流量翻...
Hostiger商家我们可能以前也是有见过的,以前他们的域名是Hostigger,后来进行微调后包装成现在的。而且推出Columbus Day哥伦布日优惠活动,提供全场的VPS主机首月7折月付2.79美元起的优惠。这里我们普及一下基础知识,Columbus Day ,即为每年10月12日,是一些美洲国家的节日,纪念克里斯托弗·哥伦布在北美登陆,为美国的联邦假日。Hostiger 商家是一个成立于2...
这两天在站长群里看到不少有使用DEDECMS织梦程序的朋友比较着急,因为前两天有看到来自DEDECMS,我们熟悉的织梦程序官方发布的公告,将会在10月25日开始全面商业用途的使用DEDECMS内容管理程序的会采用授权收费模式,如果我们有在个人或者企业商业用途的,需要联系且得到授权才可以使用,否则后面会通过维权的方式。对于这个事情,我们可能有些站长经历过,比如字体、图片的版权。以及有一些国内的CMS...