【android】通过leakCanary找出程序内存泄露点
背景
内存泄露是咱新手比较头痛的问题,因为它不像崩溃,在开发环境可以根据提示的错误信息排查问题。
你都不知道咱的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找出程序内存泄露点的更多相关文章
- 如何快速定位找出SEGV内存错误的程序Bug
通过查看php日志/usr/local/php/var/log/php-fpm.log,有如下警告信息: [16-Mar-2015 16:03:09] WARNING: [pool www] chil ...
- 找出程序GasMileage中的哪一行与下列叙述相对应:
找出程序GasMileage中的哪一行与下列叙述相对应: a.通知程序将使用Scanner类 import java.util.Scannner; b.创建一个Scanner类的对象 Scan ...
- 用windbg+sos找出程序中谁占用内存过高,谁占用CPU过高(转载)
原文地址: http://www.cnblogs.com/Lawson/archive/2011/01/23/1942692.html 很早看到windbg+sos方面的知识,一直没仔细学习,也许因为 ...
- 找出程序cpu使用率高的原因
确定是CPU过高 使用top观察是否存在CPU使用率过高现象 找出线程 对CPU使用率过高的进程的所有线程进行排序 ps H -e -o pid,tid,pcpu,cmd --sort=pcpu |g ...
- 利用WinDbg找出程序崩溃的代码行号
之前碰到论坛里有几个好友,说程序不时的崩溃,什么xxoo不能read的! 如果光要是这个内存地址,估计你会疯掉~~ 所以分享一下基本的调试技巧,需要准备的工具有WinDbg + VC6.0, 下面是自 ...
- Linux下找出吃内存的方法总结
Linux下查询进程占用的内存方法总结,假设现在有一个「php-cgi」的进程 ,进程id为「25282」. 现在想要查询该进程占用的内存大小.linux命令行下有很多的工具进行查看,现总结常见的几种 ...
- Linux中找出占用内存最多的前N个进程
一.使用ps命令 ps -aux | sort -k4nr | head -N *命令详解: 1. head:-N可以指定显示的行数,默认显示10行. 2. ps:参数a指代all——所有的进程,u指 ...
- Android Studio中找出不再使用的资源
顶部Analyze菜单中选择Run Inspection by Name 在弹出的输入框中输入unused resources
- 面试题:在一个文件中有 10G 个整数,乱序排列,要求找出中位数(内存限制为2G)
假设整数为32bit,4个字节存储 这种题目,首先想到的是分而治之.将文件中数字分组.然后遍历文件中的数字,按分组进行计数.最后找到中位数所在的分组区间 1.如果10G个整数都为同一个,那么10G整数 ...
随机推荐
- 解决spring boot中rest接口404,500等错误返回统一的json格式
在开发rest接口时,我们往往会定义统一的返回格式,列如: { "status": true, "code": 200, "message" ...
- swift - UIView 设置背景色和背景图片
代码如下: let page = UIView() page.frame = self.view.bounds //直接设置颜色 page.backgroundColor = UIColor.gree ...
- phpcms v9表单实现问答咨询功能
本文转自别人 phpcms v9的留言板插件可以安装留言板,做问答咨询,那样的话有很多东西需要修改,也有人发现phpcms v9有个表单向导功能,只能留言,不能回复,今天仿站网:新源网络工作室告诉大家 ...
- 缺陷管理工具JIRA破解版及其安装方法
JIRA是一个优秀的问题(or bugs,task,improvement,new feature )跟踪及管理软件. 它由Atlassian开发,采用J2EE技术.它正被广泛的开源软件组织,以 ...
- 安装PHP扩展-----phpredis
一.redis介绍 redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了 memcached的不足,它支持存储的value类型相 ...
- java中计算时间差
Calendar cale = null; SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" ...
- vue通信
组件实例的作用域是孤立的. 一.父子通信 父组件通过props向下传递数据给子组件,子组件通过events给父组件发送消息. 要让子组件使用父组件的数据,我们需要通过子组件的props选项.prop是 ...
- Java+selenium+Fitnesse
刚开始接触selenium是进公司后,老大给我们培训了一下UI自动化(其实也不叫培训啦,就是让我们知道有这么个东西吧,我这么说,老大看到得打人了,哈哈).要进行自动化测试,当然就得搭建一个自动化测试框 ...
- ionic 上拉加载问题(分页)
问题描述: 1.第一初始化时执行了上拉加载更多. 2.上拉时存在执行多次加载动作. angularjs的ajax不提供同步机制,是为了防止页面长时间等待,很多时候我们又需要这种同步机制交换状态,比如上 ...
- mysql 容灾 灾备 备份
一.数据备份 1.使用mysqldump命令备份 mysqldump命令将数据库中的数据备份成一个文本文件.表的结构和表中的数据将存储在生成的文本文件中. mysqldump命令的工作原理很简单.它先 ...