LeakCanary傻瓜式的内存泄露检测工具_第1页
LeakCanary傻瓜式的内存泄露检测工具_第2页
LeakCanary傻瓜式的内存泄露检测工具_第3页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、LeakCa nary傻瓜式的内存泄露检测工具在 Android 开发过程中如果需要处理图片或者大量数据的时候,常常会遇到 OOM(java.lang.OutOfMemoryError),般出现最多的是在创建 Bitmap上,也有可 能是在内存中处理了大量的数据造成。一般会针对Bitamp做下面几种的优化:1. 增加进程的内存2. 使用 Bitmap.Config.ALPHA_8图片失真)3. 显示的调用 System.gc()4. catch Exception5. 调用 bitmap.recycle()6. 缩小 bitmap 的大小(如果是读取的原图是一个大图应该先采用这种方式, Bit

2、map 如果是刚好适配屏幕的就不需要缩小了 )7使用弱引用和软引用(google已经不建议使用了,Android的GC效率非常 高,只要保证对象没有被引用即可 )但是我们会忽略掉一个问题就是什么造成了00M?般都发生00M崩溃的地方都不一定是内存泄露的地方,崩溃了的原因可能 Activity 造成的内存泄露, 也可能是操作数据库造成的内存泄露,当内存已经非常接近峰值的时候,这个 时候恰巧要创建一个 Bitmap 对象就会发生 OOM(Bitmap 对象占用的内存空间比 较大)。内存泄露每个对象都有自己的生命周期,Activity会调用onDestroy做销毁处理,但是如果使用Activity的

3、Con text调用Toast就会把这个Activity的引用传给了 Toast而Toast的生命周期不会随着 Activity的销毁而销毁,这样就造成了 Activity 的内存泄露,因为它被Toast引用着。常见的内存泄露形成的原因1. Toast 持有 Activity 的引用2. 数据库游标 Cursor 没有关闭3. Adapter 没有复用 convertView4. 对象被生命周期更长的对象引用, Activity 被静态集合引用监控内存的方式Heap Dump是一种Java比较常用的检测内存的方式,简单来说就是我们在 一个初始状态A, Dump 一次内存,在做了一些操作之后回到

4、状态 A,再Dump 一次内存。对两次Dunp的内存数据(hprof)使用分析工具做分析(MAT),根据分析的结果 就能知道是否存在内存泄露,这种方式比较复杂和繁琐并不是特别易用。Moitors:AndroidSDK自带的内存监控工具,Monitors能看到内存的变化,内存是增 加还是减少 .打开一个 Activity 会导致内存增加,关闭一个 Activity 会导致内存减 少,反复的实验如果每次打开一个 Activity 再关闭之后增加的内存不会减少就说 明这个Activity有内存泄露的问题,可以使用log辅助进行检测,这种方式的缺 点是并不是特别的准确,因为内存的释放和对象的生命周期有

5、关也和GC的调用有关。而LeakCanary就是一个简单的,方便的内存检测工具,可以轻易的发现内 存问题,还会生成更加简单清晰的报告。LeakCanaryLeakCa nary是一个开源的检测内存泄露的java库。项目地址:https:LeakCanary实际上就是在本机上自动做了 Heapdump,对生成的hprof文 件进行分析,展示结果。和手工分析 Heap Dump的方式得到的结果是一样的。下面是一个LeakCanary的结果截图:集成 LeakCanary在 build.gradle 添加依赖:dependencies leakcanary-android:3.1'relea

6、seCompileleakcanary-android-no-op:3.1'testCompileleakcanary-android-no-op:1. "3.1'使用LeakCanary会影响程序的性能,尤其是在 Heap dump和分析操作 时,不过我们可以在依赖里面指定对应的版本,debug的时候才进行分析,release的时候不进行分析。debugCompile可以使用检测版本:leakcanary-androidreleaseCompile使用 no-op 模式,即 No Operation Performed 就是不会把对 应的类库编译 ,指定类库为无用的

7、指令:leakcanary-android-no-op 设置 LeakCanary为无用指令。然后在 Application 中加入分析 Activity 的代码:public class ExampleApplication extends Application Override public void onCreate() super.onCreate();LeakCanary.install(this);这样就可以检测 Activity 的内存泄露了。内部实现使用了ActivityLifecycleCallbacks方法监控所有 Activity 的生命周期。检测其他对象LeakCan

8、ary中提供了 RefWatcher类,可以用来监控所有的对象。首先需要实例化 RefWatcher:public static RefWatcher sRefWatcher=LeakCanary.install(mContext);对于监控的对象使用:sRefWatcher.watch(this)一般我们是在对象销毁的时候对对象进行监控 ,比如内部实现的对于 Activity 的监控:privatefinalActivityLifecycleCallbackslifecycleCallbacks=newActivityLifecycleCallb acks() publicvoidonAct

9、ivityCreated(Activityactivity,BundlesavedInstanceState) public void onActivityStarted(Activity activity) public void onActivityResumed(Activity activity) public void onActivityPaused(Activity activity) public void onActivityStopped(Activity activity)publicvoidonActivitySaveInstanceState(Activityacti

10、vity,Bundle outState) public void onActivityDestroyed(Activity activity)ActivityRefWatcher.this.onActivityDestroyed(activity);只是在 onActivityDestroyed 的时候才对于 activity 进行了监控。 如何解决内存泄露 一般情况内存泄露的原因都是由于引用的使用不当造成的,而且 Android 的GC能够保证回收循环引用(如果一个循环引用没有外部引用时就会被回收),而且An droid的GC效率很高,当然GC的算法本身也在不停的改进。一般情况下我们尽量避免错误的引用方式带来的内存泄露问题:1. 生命周期长的对象引用生命周期短的对象,比如static 的对象群引用Activity2. 使用 Application

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论