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成对出现
spinservers美国圣何塞机房的独立服务器补货120台,默认接入10Gbps带宽,给你超高配置,这价格目前来看好像真的是无敌手,而且可以做到下单后30分钟内交货,都是预先部署好了的。每一台机器用户都可以在后台自行安装、重装、重启、关机操作,无需人工参与! 官方网站:https://www.spinservers.com 比特币、信用卡、PayPal、支付宝、webmoney、Payssi...
TMThosting发布了一个2021 Summer Sale活动,针对西雅图VPS主机提供月付7折优惠码,年付65折优惠码,独立服务器提供95折优惠码,本轮促销活动到7月25日。这是一家成立于2018年的国外主机商,主要提供VPS和独立服务器租用业务,数据中心包括美国西雅图和达拉斯,其中VPS基于KVM架构,都有提供免费的DDoS保护,支持选择Windows或者Linux操作系统。Budget ...
提速啦 成立于2012年,作为互联网老兵我们一直为用户提供 稳定 高速 高质量的产品。成立至今一直深受用户的喜爱 荣获 “2021年赣州安全大赛第三名” “2020创新企业入围奖” 等殊荣。目前我司在美国拥有4.6万G总内存云服务器资源,香港拥有2.2万G总内存云服务器资源,阿里云香港机房拥有8000G总内存云服务器资源,国内多地区拥有1.6万G总内存云服务器资源,绝非1 2台宿主机的小商家可比。...