背景

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

你都不知道咱的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);
}

1.3:准备工作已经完毕

接下来就是使用App,遇到内存泄漏,leakCanary会自动在手机里创建一个app来描述泄漏信息

2:测试内存泄露

我们的程序被测出了一个泄漏点,打开桌面如下图标

leakCanary对内存泄露的描述、引用链非常详细;这样人性化的提示信息,能非常快的定位问题所在

观察提示信息,我们发现出现这个问题的原因还是因为匿名类隐式引用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找出程序内存泄露点的更多相关文章

  1. 如何快速定位找出SEGV内存错误的程序Bug

    通过查看php日志/usr/local/php/var/log/php-fpm.log,有如下警告信息: [16-Mar-2015 16:03:09] WARNING: [pool www] chil ...

  2. 找出程序GasMileage中的哪一行与下列叙述相对应:

    找出程序GasMileage中的哪一行与下列叙述相对应: a.通知程序将使用Scanner类   import java.util.Scannner; b.创建一个Scanner类的对象   Scan ...

  3. 用windbg+sos找出程序中谁占用内存过高,谁占用CPU过高(转载)

    原文地址: http://www.cnblogs.com/Lawson/archive/2011/01/23/1942692.html 很早看到windbg+sos方面的知识,一直没仔细学习,也许因为 ...

  4. 找出程序cpu使用率高的原因

    确定是CPU过高 使用top观察是否存在CPU使用率过高现象 找出线程 对CPU使用率过高的进程的所有线程进行排序 ps H -e -o pid,tid,pcpu,cmd --sort=pcpu |g ...

  5. 利用WinDbg找出程序崩溃的代码行号

    之前碰到论坛里有几个好友,说程序不时的崩溃,什么xxoo不能read的! 如果光要是这个内存地址,估计你会疯掉~~ 所以分享一下基本的调试技巧,需要准备的工具有WinDbg + VC6.0, 下面是自 ...

  6. Linux下找出吃内存的方法总结

    Linux下查询进程占用的内存方法总结,假设现在有一个「php-cgi」的进程 ,进程id为「25282」. 现在想要查询该进程占用的内存大小.linux命令行下有很多的工具进行查看,现总结常见的几种 ...

  7. Linux中找出占用内存最多的前N个进程

    一.使用ps命令 ps -aux | sort -k4nr | head -N *命令详解: 1. head:-N可以指定显示的行数,默认显示10行. 2. ps:参数a指代all——所有的进程,u指 ...

  8. Android Studio中找出不再使用的资源

    顶部Analyze菜单中选择Run Inspection by Name 在弹出的输入框中输入unused resources

  9. 面试题:在一个文件中有 10G 个整数,乱序排列,要求找出中位数(内存限制为2G)

    假设整数为32bit,4个字节存储 这种题目,首先想到的是分而治之.将文件中数字分组.然后遍历文件中的数字,按分组进行计数.最后找到中位数所在的分组区间 1.如果10G个整数都为同一个,那么10G整数 ...

随机推荐

  1. 那些在BAE上部署node.js碰到的坑

    在BAE上使用node.js半年多了,其中碰到了不少因为BAE云环境限制碰到的坑 写下来大家碰到了,也不用那么麻烦的去看好几天代码了,直接对症下药 官方公布的坑有: BAE是使用package.jso ...

  2. 大圣画廊v0.2(2015.7.17)

    0.2版本号加入的功能 以tag分类图片 美化.添加瀑布流效果 添加tag页和单张图片页 添加公布图片页 以下是具体解释. 每添加一个功能,都要从模型.模板,视图,路由四个方面一一改动. 模型:添加t ...

  3. 【POJ2516】Minimum Cost

    [POJ2516]Minimum Cost 题意:有N个收购商.M个供应商.K种物品.对于每种物品,每个供应商的供应量和每个收购商的需求量已知.每个供应商与每个收购商之间运送该物品的运费已知.求满足收 ...

  4. eclipse 设置 @author @version等注释模板

    eclipse->window->preference->java->code styple->code template->Code->New Java f ...

  5. angular中的动画效果

    用angular来形成动画效果的代码如下 <!DOCTYPE html> <html lang="en" ng-app="app"> & ...

  6. tcpdump linux抓http请求头

    sudo tcpdump -i eth0 port 80 -s 1024 -l -A

  7. Java/android 里ClassName.this和this的使用

    如果在内部类里面用this就是指这个内部类的实例,而如果用OuterClassName.this就是它外面的那个类的实例 ClassName.this这个用法多用于在nested class(内部类) ...

  8. VS调用python方法

    1.  安装python3.7 2.  Vs2010中配置python: 3.添加头文件:#include <Python.h> 4.问题:error LNK2001: 无法解析的外部符号 ...

  9. d3.js 之关联数据:data操作符

    数据可视化 在可视化工作中,一个基本出发点是将不同的数值映射到不同的可视化 元素的属性上,使其表现出各自不同的视觉特征. 比如:以数组中的每一个值为直径分别创建一个圆,我们得到三个圆: 在d3中,可视 ...

  10. 提交任务到spark master -- 分布式计算系统spark学习(四)

    部署暂时先用默认配置,我们来看看如何提交计算程序到spark上面. 拿官方的Python的测试程序搞一下. qpzhang@qpzhangdeMac-mini:~/project/spark-1.3. ...