Android内存优化检测工具LeakCanary使用

news2024/11/23 17:03:08

一、什么是LeakCanary

leakCanary是Square开源框架,是一个Android和Java的内存泄露检测库。如果检测到某个activity有内存泄露,LeakCanary就是自动地显示一个通知,所以可以把它理解为傻瓜式的内存泄露检测工具。通过它可以大幅度减少开发中遇到的oom问题,大大提高APP的质量。

二、如何集成使用

Leakcanary官方链接

① LeakCanary2.0 之前

LeakCanary2.0 之前我们接入的时候需要在 Application.onCreate 方法中显式调用 LeakCanary.install(this); 开启 LeakCanary 的内存监控

1、在build.gradle中添加LeakCanary的依赖包

dependencies {
    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.6.1'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'
}

2、在我们自定义Application的onCreate方法中注册LeakCanary

public class App extends Application {

    private RefWatcher mRefWatcher;

    @Override
    public void onCreate() {
        super.onCreate();

        if (LeakCanary.isInAnalyzerProcess(this)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return;
        }

        mRefWatcher = LeakCanary.install(this);
    }

    public static RefWatcher getRefWatcher(Context context) {
        App application = (App) context.getApplicationContext();
        return application.mRefWatcher;
    }
}

正常情况下Application调用LeakCanary.install(this)后就可以正常监听该app程序的内存泄漏,如果想让LeakCanary监听指定对象的内存泄漏,我们就需要使用到RefWatcher的watch功能。

3、LeakCanary监听指定对象的内存泄漏

为了方便演示使用LeakCanary获取和解决内存泄漏的问题,我们先写一个内存泄漏的场景,我们知道最常见的内存泄漏是单列模式使用Activity的Context场景,所以我们也用单列模式来演示:

public class Singleton {
    private static Singleton singleton;
    private Context context;
    private Singleton(Context context) {
        this.context = context;
    }

    public static Singleton newInstance(Context context) {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null){//双重检查锁定
                    singleton = new Singleton(context);
                }
            }
        }
        return singleton;
    }
}

在需要监听的对象中调用RefWatcher的watch方法进行监听,比如我想监听一个Activity,我们可以在该Acitivity中onCreate方法中添加getRefWatcher().watch(this);

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    RefWatcher refWatcher = App.getRefWatcher(getActivity());
    refWatcher.watch(this);
    
    setContentView(R.layout.activity_second);
    Singleton singleton = Singleton.newInstance(this);
}

② LeakCanary2.0 之后

LeakCanary2.0开始通过库里注册的 ContentProvier 自己开启 LeakCanary 的内存监控,无需用户手动再添加初始化代码

dependencies {
  // debugImplementation because LeakCanary should only run in debug builds.
  debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
}

通过过滤 Logcat 中的 LeakCanary 标签来确认 LeakCanary 在启动时正在运行:

D/LeakCanary: LeakCanary is running and ready to detect memory leaks.

三、LeakCanary 使用

以下面的非静态内部类的泄漏场景为例,演示下 LeakCanary 的使用步骤。

public class MainActivity extends AppCompatActivity {
    //非静态内部类的静态实例引用
    public static InnerClass innerClass = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //保证非静态内部类的实例只有1个
        if (innerClass == null) {
            innerClass = new InnerClass();
        }
    }

    // 非静态内部类
    private class InnerClass {
        //...
    }
}

安装测试应用后,手机上会出现如下两个图标:
左侧的是测试应用的图标,右侧是自动安装的 LeakCanary 的图标。

在这里插入图片描述

打开测试应用,然后返回退出,人为制造内存泄漏。等待大概10秒,LeakCanary 就会检测到,并进行分析。在通知栏可以看到进度。

在这里插入图片描述
然后在分析完成后,然后在通知栏会收到通知。

在这里插入图片描述

点开通知,会打开 LeakCanary 的界面。

在这里插入图片描述

每行对应一组具有相同签名的泄漏。LeakCanary 在应用程序第一次使用该签名触发泄漏时将一行标记为“New”。点击可以查看泄漏详情。

在这里插入图片描述

这里显示 com.example.leaksample.MainActivity 这个实例发生了泄漏,红色下划波浪线标记的是可能的原因。我们分析下原因:innerClass 是非静态内部类的静态实例,它的生命周期等于应用的生命周期,持有外部类 MainActivity 的引用,故 MainActivity 无法被 GC 回收,从而导致内存泄漏。解决方案就是将 InnerClass 改为静态内部类。

另外,在 Logcat 中也可以看到 LeakCanary 的相关信息。LeakCanary 将应用中发现的泄漏分为两类:应用程序泄漏和库泄漏。

====================================
HEAP ANALYSIS RESULT
====================================
1 APPLICATION LEAKS
......
====================================
0 LIBRARY LEAK

如果有库泄漏,LeakCanary 会在其泄漏列表中将其标记为 Library Leak:

在这里插入图片描述

以上就是 LeakCanary 的使用说明, LeakCanary 只能定位到内存泄漏的大概范围,具体原因还是需要我们自己分析。内存泄露一般是代码设计存在缺陷导致的,只有多了解内存泄露的场景,才可以避免不必要的内存溢出和提高自己的编码水平。

四、LeakCanary 原理

LeakCanary 是通过在 Application 的 registerActivityLifecycleCallbacks 方法实现对 Activity 销毁监听的,该方法主要用来统一管理所有 Activity 的生命周期。所有 Activity 在销毁时在其 OnDestory 方法中都会回调 ActivityLifecycleCallbacks 的 onActivityDestroyed 方法,而 LeakCanary 要做的就是在该方法中调用 RefWatcher.watch 方法实现对 Activity 进行内存泄漏监控。
那么,LeakCanary 是如何判断某个 Activity 可能会发生内存泄漏呢?答案是:WeakReference 和 ReferenceQueue,即 LeakCanary 利用了 Java 的 WeakReference 和 ReferenceQueue,通过将 Activity 包装到 WeakReference 中,被 WeakReference 包装过的 Activity 对象如果能够被回收,则说明引用可达,垃圾回收器就会将该 WeakReference 引用存放到 ReferenceQueue 中。假如我们要监视某个 Activity 对象,LeakCanary 就会去 ReferenceQueue 找这个对象的引用,如果找到了,说明该对象是引用可达的,能被 GC 回收,如果没有找到,说明该对象有可能发生了内存泄漏。最后,LeakCanary 会将 Java 堆转储到一个 .hprof 文件中,再使用 Shark(堆分析工具)析 .hprof 文件并定位堆转储中“滞留”的对象,并对每个"滞留"的对象找出 GC roots 的最短强引用路径,并确定是否是泄露,如果泄漏,建立导致泄露的引用链。最后,再将分析完毕的结果以通知的形式展现出来。

五、参考

  • LeakCanary 中文使用说明

  • LeakCanary: 让内存泄露无所遁形

  • Android LeakCanary使用详细教程

  • Android LeakCanary的使用和原理

  • Android 内存泄漏检测工具 LeakCanary 的使用

  • LeakCanary 使用指南 (1)

  • Android 性能优化之利用 LeakCanary 检测内存泄漏及解决办法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/531859.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 并发队列详解

一,简介 1,并发队列两种实现 以ConcurrentLinkedQueue为代表的高性能非阻塞队列以BlockingQueue接口为代表的阻塞队列 2,阻塞队列与非阻塞队列的区别 当阻塞队列是空的时,从队列中获取元素的操作将会被阻塞,试图从…

【BFS】华子20230506笔试第三题(动态迷宫问题)Java实现

文章目录 题目链接思路BFS板子我的解答 题目链接 塔子哥的codeFun2000:http://101.43.147.120/p/P1251 测试样例1 输入 3 2 1 0 1 2 2 1 2 0 100 100 100 100 000 100 000 000 001输出 1测试样例2 输入 3 2 1 0 2 0 0 1 2 2 000 000 001 010 101 101 110 010 …

在docker容器中启动docker服务并实现构建多平台镜像的能力

在docker容器中启动docker服务并实现构建多平台镜像的能力 背景 在容器中运行docker,是devops中无法避免的场景,通常被应用于提供统一的镜像构建工具,出于安全考虑,不适合将主机的docker进程暴露给公司的内部人员使用&#xff0…

SpringCloud alibaba微服务b2b2c电子商务平台

1. 涉及平台 平台管理、商家端(PC端、手机端)、买家平台(H5/公众号、小程序、APP端(IOS/Android)、微服务平台(业务服务、系统服务、中间件服务) 2. 核心架构 Spring Cloud、Spring Boot2、My…

飞书开发流程

1、进入飞书并创建一个应用 链接: 创建应用 创建应用成功后需要审核通过,如果你拥有管理权限则可以自己进入管理后台通过审核,否则需要联系管理员通过审核 2、进入开发者后台 链接: 发者后台 3、在该调试平台上测试 以这个订阅审批事件为例 这一步…

DHCP协议简单配置

实验原理 网络中主机需要与外界进行通信时,需要配置自己的IP地址、网关地址、DNS服务器等网络参数信息。手工在每台主机上配置维护成本高,容易出错,而且不利于管理员统一维护。 通过DHCP地址自动配置协议,使终端设备能自动获取地址,实现即插即用且IP地址统一由服务器管理…

springboot+java充电桩充电额维修管理系统

项目介绍 Spring Boot 是 Spring 家族中的一个全新的框架,它用来简化Spring应用程序的创建和开发过程。也可以说 Spring Boot 能简化我们之前采用SSM(Spring MVC Spring MyBatis )框架进行开发的过程。 系统基于B/S即所谓浏览器/服务器模式…

STM32 学习笔记_9 定时器中断:编码器接口模式

TIM编码器接口 之前我们处理旋转编码器,是转一下中断一次,挺消耗资源的。 我们可以利用TIM的编码器功能,隔一段时间取一下旋转器值使得cnt或–,以此判断旋转位置以及计算速度,相比中断节约资源。相当于外接了一个有方…

Kubernetes那点事儿——暴露服务之Service

Kubernetes那点事儿——暴露服务之Service 前言一、Service二、Service与Pod关系三、Service常用类型ClusterIPNodePortLoadBalancer 四、Service代理模式IptablesIPVS修改代理模式 前言 K8s中,我们将应用跑在Pod里。多数情况下是一组Pod,用户如何访问这…

凌恩生物美文分享 | 提升科研有一套 | 宏基因组磷循环分析又出新!

磷是包括微生物在内的所有生命体中不可缺少的元素。在生物大分子核酸、高能量化合物ATP、以及生物体内糖代谢的某些中间体中,都有磷的存在。在自然界中,磷的循环包括可溶性无机磷的同化、有机磷的矿化、不溶性磷的溶解等。微生物分解含磷化合物的作用&am…

操作系统面试相关知识

目录 一、简介1、什么是操作系统2、操作系统主要有哪些功能? 二、操作系统结构1、什么是内核?2、什么是用户态和内核态?3、 用户态和内核态是如何切换的? 三、 进程和线程1、并行和并发有什么区别?2、什么是进程上下文…

无线传感器网络的时钟同步估计问题(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 随着无线传感器网络的快速发展,其应用领域也越来越广。在诸多的应用环境中都需要大量已同步的传感器节点通过协同作用执行一个…

Python 中IndexError: list assignment index out of range 错误解决

文章目录 Python IndexError:列表分配索引超出范围修复 Python 中的 IndexError: list assignment index out of range修复 IndexError: list assignment index out of range 使用 append() 函数修复 IndexError: list assignment index out of range 使用 insert()…

怎么把文本翻译成英文?安利三个文本翻译方法

在当今全球化的时代,跨国交流和合作已经成为常态。然而,不同语言之间的沟通障碍经常阻碍着信息传递和理解。为了帮助我们更好地进行国际交流,文本翻译英文软件应运而生。这类软件能够将各种语言的文本迅速准确地翻译成英文,使我们…

【起飞】让你电脑速度快到飞起的一些牛逼的设置整理【电脑卡顿反应慢等问题解决】

对于开发来说电脑的反应速度简直影响了思维的速度,要让电脑速度跟上我们的思维,提高工作效率,早点打卡下班回家陪老婆孩子哈哈 这篇文章主要对windows系统做的一些优化,是真的好用,仿佛在访问静态页面一样,…

超实用!年薪40W的项目经理都在用的6个项目管理软件

项目管理软件是帮助团队进行项目计划、任务分配、进度跟踪和团队协作等方面的工具,已经成为了项目经理必不可少的工具之一。 市面上的项目管理软件有很多,这就来分享一下几款我认为好用的项目管理软件! 一、六款好用的项目管理软件 1.简道…

C++开发工具 VTK技术实现三维重建CT医学影像PACS系统

一、信息管理 1、支持对患者、检查项目、申请医生、申请单据、设备等信息进行管理; 2、支持检查病人排队管理功能; 3、支持大屏幕队列显示和语音呼叫; 4、提供预约调整、插队管理和掉队处理等功能; 5、支持急诊申请优先安排。…

美股股指期货重要吗?要注意哪些风险?

美股股指期货是一种以美股股票价格指数作为标的物的金融期货合约。美股股指期货的表现对全球股指市场都有重要的影响力,具体体现在以下方面。 美股股指期货成为全球股指市场风向标 自20世纪70年代起,美国芝加哥商品交易所(CME)推…

Metasploit基础和实操-渗透测试察打一体(7)

Metasploit 基础包含专业术语,Metasploit 接口介绍,Metasploit 功能介绍 这些是弄渗透测试必须要了解的基础知识,也是0开始玩渗透测试和渗透开发的准备之一。 metasploit命令演示的环境搭建可以参考:https://luozhonghua.blog.csdn.net/article/details/123549917 作者用…

2023.05.14-微调ResNet参加kaggle上猫狗大战比赛打到99%的分类准确率_convert

文章目录 1. 前言2. 下载数据集3. 比赛成绩排名 4. baseline 5. 尝试5.1. 数据归一化(98.994%)5.2. 使用AdamW优化器(98.63%)5.3. 使用AdamW优化器SegNet模块(95.05%) 6. 结语7. 感慨 8. 代码8.1. ResNetNo…