神刀安全网

五分钟体验内存泄露检测LeakCanary


昨天感冒,大晚上10点就睡了,本来今天打算休息养伤的,谁知道大下午4点的时候传来噩耗有必解bug,只能顶着伤病来到公司了。废话少说了,今天咱们来体验一下LeakCanary的内存检测功能啦。LeakCanary这个库咋用啊,调用肯定是很简单啦,在Application类里面调用一下LeakCanary.install(this);就完事了,所以说搞应用是真他妈的简单。下面五分钟计时开始!

1.下载工程,工程的github网址:https://github.com/square/leakcanary 又是square公司的,记住这个公司,这个公司太牛逼了,什么okhttp,rxjava都是这公司搞的,就没见中国有什么创造。

五分钟体验内存泄露检测LeakCanary

网址.png

2.导入到Android studio中去,导入后是这个狗样

五分钟体验内存泄露检测LeakCanary

Android studio.png

3.然后编译了,有时会报sdk不在,你就下载sdk嘛,有时还会报下面

Error:(21, 0) CreateProcess error=2, 系统找不到指定的文件。 <a href="openFile:D:/androidstdioSDK/workspace/leakcanary/leakcanary-android/build.gradle">Open File</a>

貌似是要配git的环境变量,我懒得配,直接把这句还有java中引用的地方通通删掉,就向下图

五分钟体验内存泄露检测LeakCanary

通通删掉.png

4.然后假设你编译过了,编译不过你找我。开始执行,会给你装两个apk,分别来自leakcanary-sample和leakcanary-android文件夹
安装后是这个鸟样。

五分钟体验内存泄露检测LeakCanary

两个apk.png

然后打开左边LeakCanarySample那个apk,英文看的懂不?看不懂就别看了,这篇文章也别看了,英语都不会,还是中国人吗?英文意思,就是让你点下那个按钮,然后旋转一下屏幕。然后过个5秒,会提示了泄露了!!在状态栏可以看到,然后点一下,就会跳到上图的第二个apk去展示。

五分钟体验内存泄露检测LeakCanary

apk.png

五分钟体验内存泄露检测LeakCanary

通知栏.png

第一次运行可能通知栏提醒了给他个写存储的权限,那就给嘛。

五分钟体验内存泄露检测LeakCanary

权限.png

例子程序是下面这样的,有心的人可以看下他是怎么泄露的,反正我不知道,我就是一把梳,就是干

public class MainActivity extends Activity {    @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.main_activity);      View button = findViewById(R.id.async_task);     button.setOnClickListener(new View.OnClickListener() {       @Override public void onClick(View v) {         startAsyncTask();       }     });   }    void startAsyncTask() {     new AsyncTask<Void, Void, Void>() {       @Override protected Void doInBackground(Void... params) {         // Do some slow work in background         SystemClock.sleep(20000);         return null;       }     }.execute();   } }

看样子是有个匿名内部类AsyncTask造成的,匿名内部类持有外部类的引用,外部类是MainActivity ,MainActivity 调用destory的时候,AsyncTask还在干活呢,不能释放,AsyncTask不能释放,MainActivity 你就别想释放。然后现象就是MainActivity 调用destory后,MainActivity 对象还在内存死皮赖脸的活着,官方用语就是MainActivity 对象泄露了。

至于检测原理,搞应用的话,就不用知道了,调调api就用了,想这么多又不会加人工,是不是?开玩笑,简单说一下。我接单造个轮子你就知道了,十多行代码就搞定了,甚至有时我觉得你根本就不需要这个库,自己造个轮子就好。
按照我的理解,我要造这个轮子的话,是这样子造的,在activity的ondestory方法里面实现

  @Override   protected void onDestroy() {     super.onDestroy();    // 开启一个后台线程,这个线程不要持有activity的应用,不然泄露又说怪这个线程    Thread detectThread=new DetectThread("detectThread");     //用一个弱引用指向这个activity,并且关联到弱引用序列,我的意思是关联。怎么关联法?这个是java的基础,你去搜下WeakReferenceQueue ,当WeakReference所指对象没有强引用时,WeakReference就是被放到这个WeakReferenceQueue 序列   WeakReferenceQueue queue=new WeakReferenceQueue();    WeakReference<Activity> weakref=new WeakReference(this,queue);    detectThread.start();//开始检查   }

在另一个文件定义DetectThread

class DetectThread extend Thread {        sleep(5000);//睡个5秒去检测        gc();   //回收下垃圾先       if(queue.contains(weakref)){          Log.i(tag,"没有泄露,做的很好");       }else{         Log.i(tag,"泄露了傻逼!!!");        } }

基本原理太简单了,就是新建一个WeakReference对象指向要关注的Activity,Activity被回收的时候WeakReference对象会加到WeakReferenceQueue 队列中,检测WeakReferenceQueue队列 是否有WeakReference对象就知道有没有泄露了,有的话就没有泄露,没有的话就他妈泄露了。WeakReferenceQueue 的这一特性自己百度去,这是java基础,基础,基础!!!!!

至于真实源代码,下节我再告诉你!!其实跟我造的轮子差不多。如果我先写的话,说不定我就不开源,收费使用!!!

加班没有加班费又没有加班零食,能不能打赏我几毛钱买个烧饼?

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 五分钟体验内存泄露检测LeakCanary

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址