Android中的内存泄露(一.内存泄漏的认识以及LeakCannry的基本用法)

引导:

         在实际的Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的哥们儿应该都遇到过.但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢?下面,我就跟大家具体谈谈内存泄漏的问题.

          一问:为什么会出现内存泄漏的问题?

          答:在Android程序开发中,当一个对象已经不需要再使用了,本该被回收时,而另外一个正在使用的对象持有它的引用从而导致它不能被回收,这就导致本该被回收的对象不能被回收而停留在堆内存中.此时,内存泄漏就产生了.

          二问:内存泄漏有什么影响?

          答:它会使我们的APP的使用内存随着时间不断增加,最终造成应用程序的OOM.这种不算低级的低级错误是我们有理想有抱负的Android攻城狮不能容忍的!!!

          OOM:out of memory,由于Android系统为为每个应用程序分配的内存有限,当一个应用中产生的内存泄漏比较多时,会导致应用所需的内存超过系统分配的内存限额,这就造成了OOM,使应用崩溃.


-------------------------------------------------------------------------不是很华丽的分割线-----------------------------------------------------------------------

          实际开发中,很多互联网都会花很大力气去处理内存泄漏这个问题,以提高APP的质量.今天先跟大家介绍一款目前市面上很多互联网公司都在使用的自动检测内存泄漏的开源工具--LeakCanary.

          首先,我们去github上下载它的官方开源demo,直接将zip包down下来(https://github.com/square/leakcanary):

            

         下载成功后直接用studio打开工程,查看官方内存泄漏的例子:

                 

            红框中注释告诉我们该demo内存泄漏的原因:此AsyncTask是一个匿名内部类,隐式持有外部类(MainActivity)的引用,当activity被销毁时,如果AsyncTask没有执行完成,则MainActivity将会泄漏.

         了解这个demo内存泄露的原因后,我们运行该demo,可以看到下图所示的画面:

                      

           下来,我们做这样的操作:点击Button后,在20秒内我们点击手机返回键,关闭该activity.

          重点来了, 关闭MainActivity大概10秒钟后,我们可以再通知栏看到一个内存内存泄漏的提示:

        

         点击通知栏提示,可以看到内存泄漏的详细内容:

        

         在这个demo中,我们可以看到,由于子线程的引用,导致MainActivity泄漏了263KB,看起来确实无伤大雅,但是在实际开发中,如果我们不注意,这里泄漏几百kb,那里泄漏几百kb,在剬的操作中,导致整个app的内存不断增加,app越来越卡,直至OOM.

         那么这个泄漏如何更正呢?


-------------------------------------------------------------------------不是很华丽的分割线-----------------------------------------------------------------------

新建项目引入LeakCanary:

             1.在studio中新建一个项目

         2.配置build.gradle文件

          dependencies {

              debugCompile 'com.squareup.leakcanary:leakcanary-android:1.4-beta2'

              releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'

              testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.4-beta2'

           }

           如下图:


          

              

          说明:releaseCompile 和debugCompile 的含义,设置我们仅在我们开发Debug的时候,LeakCanary才会帮我们去检测内存 泄漏,release打包的时候LeakCanary不生效。

           添加后点击Sync Now:

         

            

         同步之后,Gradle会帮助我们去获取库文件,获取成功后可在我们External Libraries下面查看:

          

             

              

          3.在你的应用里写一个自定义 Application ,并在其中“安装” LeakCannary

             添加一个类,叫MyApplication ,继承自Application

             public class MyApplication extends Application {

 

                     @Override

                     public void onCreate() {

                     super.onCreate();

                     LeakCanary.install(this);

                     }

            }

          记得把它作为 android:name 配到 AndroidManifest.xml 的Application 节点下。    android:name=".MyApplication"

          位置如图所示:

         


         OK到这里,我们基本就把环境配置好了,不用添加任何代码,LeakaCanary会默认帮我们去检测Activity的内存泄漏.

         接下来,我们依照官方的demo写一个内存泄漏的代码,使用 LeakaCanary检测:

         1.UI布局:

        

            2.在MainActivity中添加代码:

            

           

           3.运行代码,点击button后等待10秒,LeakCanary提示内存泄漏。

             OK ,上面的代码和官方的例子一模一样,它是我们的AsyncTask造成了内存泄漏,如何改正呢?

             分析原因: AsyncTask是一个匿名的内部类,隐式的持有外部类(MainActivity)的引用,当activity被销毁的时候,如果AsyncTask(代码sleep 20秒,模拟了一个耗时操作)没有执行完成,则MainActivity将会泄漏。

         

             那么,既然是匿名内部类的问题,那么我们换个方式,我们可以使用静态内部类去解决它,代码示意如下,我们自己添加一个静态内部类,继承自AsyncTask.

            

               这样一来,静态内部类就不会隐式的持有外部类的引用.

               修改后运行代码:

               1. 点击按钮,

               2. 点击手机返回键,等10秒。

               3. LeakCanary没有检测出内存泄漏。改正完毕。

              

               以上.






评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值