LeakCa nary傻瓜式的内存泄露检测工具
在Android开发过程中如果需要处理图片或者大量数据的时候常常会遇到OOMjava. lang.OutOfMemoryError ,—般出现最多的是在创建Bitmap上也有可能是在内存中处理了大量的数据造成。
般会针对Bitamp做下面几种的优化:
1 .增加进程的内存
2.使用Bitmap.Config.ALPHA_8图片失真)
3.显示的调用System.gc()
4. catch Exception
5.调用b itm ap.recycl e()
6.缩小bitmap的大小如果是读取的原图是一个大图应该先采用这种方式Bitmap如果是刚好适配屏幕的就不需要缩小了
7.使用弱引用和软引用google已经不建议使用了 Android的GC效率非常高只要保证对象没有被引用即可
但是我们会忽略掉一个问题就是什么造成了 OOM?—般都发生OOM崩溃的地方都不一定是内存泄露的地方崩溃了的原因可能Activity造成的内存泄露也可能是操作数据库造成的内存泄露当内存已经非常接近峰值的时候这个时候恰巧要创建一个Bitmap对象就会发生OOMBitmap对象占用的内存空间比较大 。
内存泄露
每个对象都有自己的生命周期 Activity会调用onDestroy做销毁处理但是如果使用Activity的Con text调用Toast就会把这个Activity的引用传给了Toast而Toast的生命周期不会随着Activity的销毁而销毁这样就造成了Activity的内存泄露因为它被Toast引用着。
常见的内存泄露形成的原因:
1/5
1 . Toast持有Activity的引用
2.数据库游标Cu rsor没有关闭
3.Adapter没有复用convertView
4.对象被生命周期更长的对象引用 Activity被静态集合引用
监控内存的方式
HeaP Dump是一种Java比较常用的检测内存的方式简单来说就是我们在一个初始状态ADump一次内存在做了一些操作之后回到状态A再Dump一次内存。
对两次Du n p的内存数据h p rof使用分析工具做分析MAT ,根据分析的结果就能知道是否存在内存泄露这种方式比较复杂和繁琐并不是特别易用。
M o i t o rs:
AndroidSDK自带的内存监控工具Monitors能看到内存的变化内存是增加还是减少•打开一个Activity会导致内存增加关闭一个Activity会导致内存减少反复的实验如果每次打开一个Activity再关闭之后增加的内存不会减少就说明这个Activity有内存泄露的问题可以使用log辅助进行检测这种方式的缺点是并不是特别的准确因为内存的释放和对象的生命周期有关也和 GC的调用有关。
而LeakCanary就是一个简单的方便的内存检测工具可以轻易的发现内存问题还会生成更加简单清晰的报告。
LeakCanary
LeakCa nary是一个开源的检测内存泄露的java库。项目地址:https:
LeakCanary实际上就是在本机上自动做了Heapdump,对生成的hprof文件进行分析展示结果。和手工分析HeaPDump的方式得到的结果是一样的。
2/5
F面是一个LeakCanary的结果截图:
集成LeakCanary
在bui ld.gradle添加依赖:dependencies{leakcanary-and roid:
1 ."
3.1'releaseCompi le leakcanary-android-no-op:
1 ."
3.1'testCompi le leakcanary-android-no-op:
1 ."
3.1'使用LeakCanary会影响程序的性能尤其是在Heap dump和分析操作时不过我们可以在依赖里面指定对应的版本 debug的时候才进行分析release的时候不进行分析。debugCompi le可以使用检测版本:leakcanary-and roid releaseCo mp i le使用no-op模式即No Op eratio n P erformed就是不会把对应的类库编译,指定类库为无用的指
令:leakcanary-android-no-op设置LeakCanary为无用指令。
3/5
然后在Appl ication中加入分析Activity的代码publ ic class ExampleAppl ication extends Appl ication {
@Override publ ic void onCreate() {super.onCreate();
LeakCanary. instal l(this);}}
这样就可以检测Activity的内存泄露了。内部实现使用了
ActivityLifecycleCal lbacks方法监控所有Activity的生命周期。
检测其他对象
LeakCanary中提供了RefWatcher类,可以用来监控所有的对象。
首先需要实例化RefWatcher:publ ic static RefWatcher sRefWatcher=LeakCanary. instal l(mContext);
对于监控的对象使用sRefWatcher.watch(this)
一般我们是在对象销毁的时候对对象进行监控 ,比如内部实现的对于Activity 的监控:privatefinalActivityLifecycleCal lbacksl ifecycleCal lbacks=newActivityLifecycleCal lb acks() {publ icvoidonActivityCreated(Activityactivity,BundlesavedInstanceState) {}publ ic void onActivityStarted(Activity activity) {}publ ic void onActivityResumed(Activity activity){}publ ic void onActivityPaused(Activity activity) {}publ ic void onActivityStopped(Activity activity)
{}publ icvoidonActivitySaveInstanceState(Activityactivity,Bundle outState) {}publ ic void onActivityDestroyed(Activity activity)
{ActivityRefWatcher.th is.onActivityDestroyed(activity);}
4/5
};
只是在onActivityDestroyed的时候才对于activity进行了监控。
如何解决内存泄露
一般情况内存泄露的原因都是由于引用的使用不当造成的而且Android的GC能够保证回收循环引用如果一个循环引用没有外部引用时就会被回收 而且An droid的GC效率很高当然GC的算法本身也在不停的改进。
般情况下我们尽量避免错误的引用方式带来的内存泄露问题
1 .生命周期长的对象引用生命周期短的对象比如 static的对象群引用Activity
2.使用Appl ication的Context对象而不是Activity的Context
3.避免非静态类的内部类对于类的隐式引用使用静态的内部类
4.使用And roid的缓存机制比如ListView的复用机制
5.手动关闭资源比如Curous的关闭
6. registerReceiver禾口unRegisterReceiver成对出现
5/5
Virtono最近推出了夏季促销活动,为月付、季付、半年付等提供9折优惠码,年付已直接5折,而且下单后在LET回复订单号还能获得双倍内存,不限制付款周期。这是一家成立于2014年的国外VPS主机商,提供VPS和服务器租用等产品,商家支持PayPal、信用卡、支付宝等国内外付款方式,可选数据中心包括罗马尼亚、美国洛杉矶、达拉斯、迈阿密、英国和德国等。下面列出几款VPS主机配置信息,请留意,下列配置中...
商家介绍:星梦云怎么样,星梦云好不好,资质齐全,IDC/ISP均有,从星梦云这边租的服务器均可以备案,属于一手资源,高防机柜、大带宽、高防IP业务,一手整C IP段,四川电信,星梦云专注四川高防服务器,成都服务器,雅安服务器,。活动优惠促销:1、成都电信夏日激情大宽带活动机(封锁UDP,不可解封):机房CPU内存硬盘带宽IP防护流量原价活动价开通方式成都电信优化线路2vCPU2G40G+60G21...
NameCheap商家如今发布促销活动也是有不小套路的,比如会在提前一周+的时间告诉你他们未来的活,比如这次2021年的首次活动就有在一周之前看到,但是这不等到他们中午一点左右的时候才有正式开始,而且我确实是有需要注册域名,等着看看是否有真的折扣,但是实际上.COM域名力度也就一般需要51元左右,其他地方也就55元左右。当然,这次新年的首次活动不管如何肯定是比平时便宜一点点的。有新注册域名、企业域...