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成对出现
Boomer.Host是一家比较新的国外主机商,虽然LEB自述 we’re now more than 2 year old,商家提供虚拟主机和VPS,其中VPS主机基于OpenVZ架构,数据中心为美国得克萨斯州休斯敦。目前,商家在LET发了两款特别促销套餐,年付最低3.5美元起,特别提醒:低价低配,且必须年付,请务必自行斟酌确定需求再入手。下面列出几款促销套餐的配置信息。CPU:1core内存:...
易探云服务器怎么过户/转让?易探云支持云服务器PUSH功能,该功能可将云服务器过户给指定用户。可带价PUSH,收到PUSH请求的用户在接收云服务器的同时,系统会扣除接收方的款项,同时扣除相关手续费,然后将款项打到发送方的账户下。易探云“PUSH服务器”的这一功能,可以让用户将闲置云服务器转让给更多需要购买的用户!易探云服务器怎么过户/PUSH?1.PUSH双方必须为认证用户:2.买家未接收前,卖家...
关于TTCLOUD服务商在今年初的时候有介绍过一次,而且对于他们家的美国圣何塞服务器有过简单的测评,这个服务商主要是提供独立服务器业务的。目前托管硬件已经达到5000台服务器或节点,主要经营圣何塞,洛杉矶以及日本东京三个地区的数据中心业务。这次看到商家有推出了新上架的日本独立服务器促销活动,价格 $70/月起,季付送10Mbps带宽。也可以跟进客户的需求进行各种DIY定制。内存CPU硬盘流量带宽价...