内存LeakCanary傻瓜式的内存泄露检测工具

内存检测工具  时间:2021-01-12  阅读:()

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成对出现

妮妮云80元/月,香港站群云服务器 1核1G

妮妮云的来历妮妮云是 789 陈总 张总 三方共同投资建立的网站 本着“良心 便宜 稳定”的初衷 为小白用户避免被坑妮妮云的市场定位妮妮云主要代理市场稳定速度的云服务器产品,避免新手购买云服务器的时候众多商家不知道如何选择,妮妮云就帮你选择好了产品,无需承担购买风险,不用担心出现被跑路 被诈骗的情况。妮妮云的售后保证妮妮云退款 通过于合作商的友好协商,云服务器提供2天内全额退款,超过2天不退款 物...

GreenCloudVPS$20/年,新加坡/美国/荷兰vps/1核/1GB/30GB,NVMe/1TB流量/10Gbps端口/KVM

greencloudvps怎么样?greencloudvps是一家国外主机商,VPS数据中心多,之前已经介绍过多次了。现在有几款10Gbps带宽的特价KVM VPS,Ryzen 3950x处理器,NVMe硬盘,性价比高。支持Paypal、支付宝、微信付款。GreenCloudVPS:新加坡/美国/荷兰vps,1核@Ryzen 3950x/1GB内存/30GB NVMe空间/1TB流量/10Gbps...

Dynadot多种后缀优惠域名优惠码 ,.COM域名注册$6.99

Dynadot 是一家非常靠谱的域名注册商家,老唐也从来不会掩饰对其的喜爱,目前我个人大部分域名都在 Dynadot,还有一小部分在 NameCheap 和腾讯云。本文分享一下 Dynadot 最新域名优惠码,包括 .COM,.NET 等主流后缀的优惠码,以及一些新顶级后缀的优惠。对于域名优惠,NameCheap 的新后缀促销比较多,而 Dynadot 则是对于主流后缀的促销比较多,所以可以各取所...

内存检测工具为你推荐
网站空间什么叫域名?空间?注册国际域名注册国际域名时的地址怎么填写?海外域名我想了解一下“国内域名”,“国外域名”以及“海外服务器”这三个方面的一些知识海外域名怎么挑选合适的国外域名?虚拟主机软件常见的虚拟机软件有哪几种?郑州虚拟主机虚拟主机哪个好点,用过的推荐下美国虚拟主机购买我公司需要购买美国的虚拟主机。但是为什么有的海外主机很便宜!有的却很贵呢。 质量如何区分!有没办法去虚拟主机试用30天虚拟主机返佣是怎么回事?域名解析域名解析是什么意思啊?中文域名什么是中文域名?
北京vps enom hostmonster 主机 全球付 台湾谷歌网址 免费网站申请 linux空间 jsp空间 谁的qq空间最好看 183是联通还是移动 爱奇艺vip免费领取 支持外链的相册 多线空间 电信托管 个人免费主页 双线机房 四川电信商城 国内域名 国外的代理服务器 更多