码迷,mamicode.com
首页 > 移动开发 > 详细

【android】通过leakCanary找出程序内存泄露点

时间:2015-09-21 17:23:19      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:

背景

内存泄露是咱新手比较头痛的问题,因为它不像崩溃,在开发环境可以根据提示的错误信息排查问题。

你都不知道咱的app是否哪个犄角旮旯藏着一个吞噬内存的黑洞。

排查android 内存泄露比较底层高端的做法:使用官方的内存分析工具(MAT), 比较好的两篇入门文章:(一) 和 (二)

技术分享

 

然而这个过程比较考验耐心,

咱新手也可以选择另外一款App的插件leakcanary,集成了这个插件,我们在使用app的时候,遇到内存泄露点,它就会弹出通知,并告知泄漏点(release下不会弹框)。

实战

咱们就用自己做的博客园app客户端来测试内存泄露的问题。

1:集成leakCanary

1.1:build.gradle里面:

 dependencies {
   debugCompile ‘com.squareup.leakcanary:leakcanary-android:1.3.1‘
   releaseCompile ‘com.squareup.leakcanary:leakcanary-android-no-op:1.3.1‘
 }

 

1.2:Application父类的onCreate方法中添加:

 @Override
    public void onCreate() {
        super.onCreate();
        LeakCanary.install(this);
}

 

2:测试内存泄露

leakCanary会自动在手机里创建一个报告的app,点开它就可以看内存泄露的一些信息(如果有)

技术分享

 

在使用咱的客户端时,它提示发现了一处内存泄露,类名,引用链都给出来了;这样人性化的提示信息,能非常快的定位问题所在

技术分享

 

观察提示信息,我们发现出现这个问题的原因还是因为匿名类隐式引用Activity,导致Activity回收不掉。出现问题的地方:

mWebView.setOnScrollListener(new ScrollWebView.OnScrollListener() {
            @Override
            public void onScroll(int x, int y) {
                switchActionBar(y - mPreviousYPos);
                mPreviousYPos = y;
            }
        });

 

 

解决之道有很多,在回收的时候,只要确保该Activity没被其他对象持有强引用就好了。

咱的解决之道是使用弱引用,这样调用者就不用关心强引用可能导致的内存泄露的问题了。

 

package zhexian.learn.cnblogs.ui;

import android.content.Context;
import android.util.AttributeSet;
import android.webkit.WebView;

import java.lang.ref.WeakReference;

/**
 * 可以滚动的webView
 */
public class ScrollWebView extends WebView {
    private WeakReference<OnScrollListener> mOnScrollListener;

    public ScrollWebView(final Context context) {
        super(context);
    }

    public ScrollWebView(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrollWebView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        OnScrollListener listener = mOnScrollListener.get();

        if (listener != null)
            listener.onScroll(l, t);
    }

    public void setOnScrollListener(final OnScrollListener onScrollListener) {
        mOnScrollListener =new WeakReference<>(onScrollListener) ;
    }

    public interface OnScrollListener {
        void onScroll(int x, int y);
    }
}

 

【android】通过leakCanary找出程序内存泄露点

标签:

原文地址:http://www.cnblogs.com/kimmy/p/4826432.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!