LeakCanary

LeakCanary

文章目录

  • LeakCanary
    • 一、内容
      • 1. 使用方法
      • 2. 工作原理
      • 3.工作流程
    • 参考资料

一、内容

LeakCanary 是在 Android 项目中,用于检测内存泄露,优化性能的工具。

1. 使用方法

本文使用版本为 2.5 版本,相比于 2.0 之前的版本,2.0 之后的版本在使用上简洁了很多,只需要在 dependencies 添加 LeakCanary 依赖项即可。

dependencies {

  debugImplementation ("com.squareup.leakcanary:leakcanary-android:2.5")

}

之后运行需要检测的项目,就可在控制台看到 LeakCanary 在启动时正在运行的打印信息:

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

运行测试应用后桌面会出现两个图标:左侧的是测试应用的图标,右侧是自动安装的 LeakCanary 的图标。
在这里插入图片描述

2. 工作原理

LeakCanary 本质上是一个基于 MAT 进行 Android 应用程序内存泄漏自动化检测的的开源工具,我们可以通过集成 LeakCanary 提供的 jar 包到自己的工程中,一旦检测到内存泄漏,LeakCanary 就会 dump Memory 信息,并通过另一个进程分析内存泄漏的信息并展示出来,随时发现和定位内存泄漏问题。

LeakCanary 是使用了 ContentProvider 进行初始化,即在打包的过程中来自不同 module 的 ContentProvider最后都会 merge 到一个文件中,启动 app 的时候 ContentProvider 是自动安装,利用它安装比 Application 的 OnCreate 还早来实现对 Activity 整个生命周期的监听。

3.工作流程

1)检测保留对象

LeakCanary 自动检测四种对象的泄露:1. 销毁的 Activity 实例;2. 销毁的 Fragment 实例;3. 销毁的片段 View 实例;4. 清除 ViewModel 实例。

LeakCanary 基于 ObjectWatcher Android 的 library,它与 Android 的生命周期挂钩,当 Activity 和 Fragment 被销毁并且应该被做为垃圾回收时自动检测。应当被销毁的对象传递给 ObjectWatcher,ObjectWatcher 持有这些被销毁对象的弱引用,如果弱引用在等待 5 秒钟后运行垃圾收集器后发现被销毁对象仍未被清除,那么被观察者就认为这些对象在生命周期结束后仍保留,并存在潜在的泄露,LeakCanary 就会在 Logcat 中输出日志。

09-26 13:07:18.785 23731 23731 D LeakCanary: LeakCanary is running and ready to detect memory leaks.
09-26 13:07:20.368 23731 23753 D LeakCanary: Setting up flushing for Thread[LeakCanary-Heap-Dump,5,main]
09-26 13:07:20.369 23731 23753 D LeakCanary: Setting up flushing for Thread[queued-work-looper,5,main]
09-26 13:07:20.369 23731 23753 D LeakCanary: Setting up flushing for Thread[InsetsAnimations,5,main]
09-26 13:07:21.062 23731 23731 D LeakCanary: Watching instance of androidx.fragment.app.FragmentManagerViewModel (androidx.fragment.app.FragmentManagerViewModel received ViewModel#onCleared() callback) with key f676ad97-f211-4a87-a7f8-55d501e03bc7
09-26 13:07:21.062 23731 23731 D LeakCanary: Watching instance of androidx.lifecycle.SavedStateHandlesVM (androidx.lifecycle.SavedStateHandlesVM received ViewModel#onCleared() callback) with key 4438d66f-e78c-47c0-a494-644154121e99
09-26 13:07:21.062 23731 23731 D LeakCanary: Watching instance of leakcanary.internal.ViewModelClearedWatcher (leakcanary.internal.ViewModelClearedWatcher received ViewModel#onCleared() callback) with key 25e62c20-6dcd-4a0d-9c63-68b0745eeadf
09-26 13:07:21.063 23731 23731 D LeakCanary: Watching instance of androidx.lifecycle.ReportFragment (androidx.lifecycle.ReportFragment received Fragment#onDestroy() callback) with key 76e52b86-4f2f-47e9-ab40-63c2dd2eac8a
09-26 13:07:21.064 23731 23731 D LeakCanary: Watching instance of com.lambda.binder.activity.MyClientActivity (com.lambda.binder.activity.MyClientActivity received Activity#onDestroy() callback) with key ecfabc8d-7c5b-4c83-b910-d9c0401587b8
09-26 13:07:26.273 23731 23754 D LeakCanary: Found 4 objects retained, dumping heap now (app is invisible)
09-26 13:07:26.304 23731 23754 D LeakCanary: Removing 1 heap dumps
09-26 13:07:29.900 23731 23777 D LeakCanary: Analysis in progress, working on: PARSING_HEAP_DUMP
09-26 13:07:31.353 23731 23777 D LeakCanary: Analysis in progress, working on: EXTRACTING_METADATA
09-26 13:07:31.405 23731 23777 D LeakCanary: Analysis in progress, working on: FINDING_RETAINED_OBJECTS
09-26 13:07:31.555 23731 23777 D LeakCanary: Analysis in progress, working on: FINDING_PATHS_TO_RETAINED_OBJECTS
09-26 13:07:32.896 23731 23753 D LeakCanary: Setting up flushing for Thread[IntentService[HeapAnalyzerService],5,main]
09-26 13:07:35.002 23731 23777 D LeakCanary: Analysis in progress, working on: FINDING_DOMINATORS
09-26 13:07:35.084 23731 23777 D LeakCanary: Found 4 retained objects
09-26 13:07:35.085 23731 23777 D LeakCanary: Found 4 paths to retained objects, down to 1 after removing duplicated paths
09-26 13:07:35.085 23731 23777 D LeakCanary: Analysis in progress, working on: INSPECTING_OBJECTS
09-26 13:07:35.099 23731 23777 D LeakCanary: Analysis in progress, working on: COMPUTING_NATIVE_RETAINED_SIZE
09-26 13:07:35.355 23731 23777 D LeakCanary: Analysis in progress, working on: COMPUTING_RETAINED_SIZE
09-26 13:07:35.543 23731 23777 D LeakCanary: Analysis in progress, working on: BUILDING_LEAK_TRACES
09-26 13:07:35.554 23731 23777 D LeakCanary: Analysis in progress, working on: REPORTING_HEAP_ANALYSIS
09-26 13:07:35.577 23731 23777 D LeakCanary:09-26 13:07:35.577 23731 23777 D LeakCanary: ====================================
09-26 13:07:35.577 23731 23777 D LeakCanary: HEAP ANALYSIS RESULT
09-26 13:07:35.577 23731 23777 D LeakCanary: ====================================
09-26 13:07:35.577 23731 23777 D LeakCanary: 1 APPLICATION LEAKS
09-26 13:07:35.577 23731 23777 D LeakCanary: 
09-26 13:07:35.577 23731 23777 D LeakCanary: References underlined with "~~~" are likely causes.
09-26 13:07:35.577 23731 23777 D LeakCanary: Learn more at https://squ.re/leaks.
09-26 13:07:35.577 23731 23777 D LeakCanary: 
09-26 13:07:35.577 23731 23777 D LeakCanary: 169456 bytes retained by leaking objects
09-26 13:07:35.577 23731 23777 D LeakCanary: Signature: 37f15b5a51deab884265aa64df7c089bb978ef5
09-26 13:07:35.577 23731 23777 D LeakCanary: ┬───
09-26 13:07:35.577 23731 23777 D LeakCanary: │ GC Root: System class
09-26 13:07:35.577 23731 23777 D LeakCanary:09-26 13:07:35.577 23731 23777 D LeakCanary: ├─ android.provider.FontsContract class
09-26 13:07:35.577 23731 23777 D LeakCanary:Leaking: NO (Application↓ is not leaking and a class is never leaking)
09-26 13:07:35.577 23731 23777 D LeakCanary: │    ↓ static FontsContract.sContext
09-26 13:07:35.577 23731 23777 D LeakCanary: ├─ android.app.Application instance
09-26 13:07:35.577 23731 23777 D LeakCanary:Leaking: NO (Application is a singleton)
09-26 13:07:35.577 23731 23777 D LeakCanary: │    mBase instance of android.app.ContextImpl, not wrapping known Android context
09-26 13:07:35.577 23731 23777 D LeakCanary: │    ↓ Application.mLoadedApk
09-26 13:07:35.577 23731 23777 D LeakCanary:~~~~~~~~~~
09-26 13:07:35.577 23731 23777 D LeakCanary: ├─ android.app.LoadedApk instance
09-26 13:07:35.577 23731 23777 D LeakCanary:Leaking: UNKNOWN
09-26 13:07:35.577 23731 23777 D LeakCanary:Retaining 1152 bytes in 23 objects
09-26 13:07:35.577 23731 23777 D LeakCanary: │    mApplication instance of android.app.Application
09-26 13:07:35.577 23731 23777 D LeakCanary: │    ↓ LoadedApk.mReceivers
09-26 13:07:35.577 23731 23777 D LeakCanary:~~~~~~~~~~
09-26 13:07:35.577 23731 23777 D LeakCanary: ├─ android.util.ArrayMap instance
09-26 13:07:35.577 23731 23777 D LeakCanary:Leaking: UNKNOWN
09-26 13:07:35.577 23731 23777 D LeakCanary:Retaining 689 bytes in 11 objects
09-26 13:07:35.577 23731 23777 D LeakCanary: │    ↓ ArrayMap.mArray
09-26 13:07:35.577 23731 23777 D LeakCanary:~~~~~~
09-26 13:07:35.577 23731 23777 D LeakCanary: ├─ java.lang.Object[] array
09-26 13:07:35.577 23731 23777 D LeakCanary:Leaking: UNKNOWN
09-26 13:07:35.577 23731 23777 D LeakCanary:Retaining 648 bytes in 9 objects
09-26 13:07:35.577 23731 23777 D LeakCanary: │    ↓ Object[].[0]
09-26 13:07:35.577 23731 23777 D LeakCanary:~~~
09-26 13:07:35.577 23731 23777 D LeakCanary: ╰→ com.lambda.binder.activity.MyClientActivity instance
09-26 13:07:35.577 23731 23777 D LeakCanary:Leaking: YES (ObjectWatcher was watching this because com.lambda.binder.activity.MyClientActivity received
09-26 13:07:35.577 23731 23777 D LeakCanary:Activity#onDestroy() callback and Activity#mDestroyed is true)
09-26 13:07:35.577 23731 23777 D LeakCanary:Retaining 169456 bytes in 3671 objects
09-26 13:07:35.577 23731 23777 D LeakCanary: ​     key = ecfabc8d-7c5b-4c83-b910-d9c0401587b8
09-26 13:07:35.577 23731 23777 D LeakCanary: ​     watchDurationMillis = 5227
09-26 13:07:35.577 23731 23777 D LeakCanary: ​     retainedDurationMillis = 191
09-26 13:07:35.577 23731 23777 D LeakCanary: ​     mApplication instance of android.app.Application
09-26 13:07:35.577 23731 23777 D LeakCanary: ​     mBase instance of androidx.appcompat.view.ContextThemeWrapper, not wrapping known Android context
09-26 13:07:35.577 23731 23777 D LeakCanary: ====================================
09-26 13:07:35.577 23731 23777 D LeakCanary: 0 LIBRARY LEAKS
09-26 13:07:35.577 23731 23777 D LeakCanary: 
09-26 13:07:35.577 23731 23777 D LeakCanary: A Library Leak is a leak caused by a known bug in 3rd party code that you do not have control over.
09-26 13:07:35.577 23731 23777 D LeakCanary: See https://square.github.io/leakcanary/fundamentals-how-leakcanary-works/#4-categorizing-leaks
09-26 13:07:35.577 23731 23777 D LeakCanary: ====================================
09-26 13:07:35.577 23731 23777 D LeakCanary: METADATA
09-26 13:07:35.577 23731 23777 D LeakCanary: 
09-26 13:07:35.577 23731 23777 D LeakCanary: Please include this in bug reports and Stack Overflow questions.
09-26 13:07:35.577 23731 23777 D LeakCanary: 
09-26 13:07:35.577 23731 23777 D LeakCanary: Build.VERSION.SDK_INT: 30
09-26 13:07:35.577 23731 23777 D LeakCanary: Build.MANUFACTURER: Letv
09-26 13:07:35.577 23731 23777 D LeakCanary: LeakCanary version: 2.5
09-26 13:07:35.577 23731 23777 D LeakCanary: App process name: com.lambda.binder
09-26 13:07:35.577 23731 23777 D LeakCanary: Stats: LruCache[maxSize=3000,hits=3074,misses=61336,hitRate=4%]
09-26 13:07:35.577 23731 23777 D LeakCanary: RandomAccess[bytes=2981240,reads=61336,travel=25232087720,range=20535346,size=26457885]
09-26 13:07:35.577 23731 23777 D LeakCanary: Analysis duration: 5652 ms
09-26 13:07:35.577 23731 23777 D LeakCanary: Heap dump file path: /storage/emulated/0/Download/leakcanary-com.lambda.binder/2024-09-26_13-07-26_360.hprof
09-26 13:07:35.577 23731 23777 D LeakCanary: Heap dump timestamp: 1727327255551
09-26 13:07:35.577 23731 23777 D LeakCanary: Heap dump duration: 3485 ms
09-26 13:07:35.577 23731 23777 D LeakCanary: ====================================

并且在手机上也会弹出提示:
在这里插入图片描述

2)转储堆

在未被正常清除的对象达到一定数量后,LeakCanary 会将其转储到 Android 文件系统上的 .hprof 文件中。这个数量当应用程序的状态是可见的时候,默认阀值为 5;当应用程序是不可见时,默认阀值为 1。转储堆会使应用程序停止运行一小段时间,并弹出提示。

3)分析堆

LeakCanary 是使用 shark 来解析 .hprof 文件并定位 Java 堆中保留的对象,并对于每个被保留的对象,LeakCanary 会找出阻止该对象被回收的引用链,即泄露路径。确定泄露路径后,LeakCanary 使用它对 Android 框架的了解来找出在泄露路径上是谁泄露了。分析完成之后,LeakCanary 会显示带有摘要的通知,

在这里插入图片描述

并将结果打印在 Logcat 中。LeakCanary 会为每个泄露跟踪创建一个签名,并将具有相同签名的泄露(即由相同错误引起的泄露)组合在一起。
在这里插入图片描述

点击进去就可看到详细的泄露路径,每个路径中的每个节点都对应着一个 Java 对象。

在这里插入图片描述

在泄露路径的顶部是 GC Root,它是一些总是可达的特殊对象。接下来就注意看 Leaking 的状态,分为 YES、NO、UNKNOWN 三种,NO 就是没泄露,UNKNOWN 表示这里可能出现了内存泄漏,YES 表示此处存在泄露。一般推断内存泄露是从最后一个没有泄漏的节点(Leaking:NO)到第一个泄漏的节点(Leaking:YES)之间的引用。

4)分类泄露

LeakCanary 将泄露分为两类:应用程序泄露和库泄露。库泄露是由于第三方库造成,带有 LibraryLeak 标签;应用程序泄露一般是由于程序员异常操作造成。

参考资料

Android 引起内存泄漏的几种情况

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式:Keil的Code、RW、RO、ZI段的解析

相关阅读 嵌入式https://blog.csdn.net/weixin_45791458/category_12768532.html // 例1 int main(void) {HAL_Init(); /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟,72M */delay_init(72); …

[PHP]重复的Notice错误信息

<?php $a []; var_dump($a[name]);执行结果&#xff1a; 原因&#xff1a; display_errors和error_reporting都打开了Notice错误信息

前缀和一>寻找数组的中心下标

1.题目&#xff1a; 2.解析&#xff1a; 如果暴力解法时间复杂度是O(N^2)&#xff0c;定个&#xff0c;i&#xff0c;遍历左边右边&#xff1b; 这里可以优化为前缀和的做法&#xff0c;其实就是个动态规划。 代码&#xff1a; public int pivotIndex(int[] nums) {int n n…

如何利用边缘计算网关进行工厂设备数据采集?天拓四方

边缘计算网关集成了数据采集、处理和传输功能&#xff0c;位于传感器和执行器组成的设备层与云计算平台之间。它能够实时处理和响应本地设备的数据请求&#xff0c;减轻云平台的压力&#xff0c;提高数据处理的速度和效率。同时&#xff0c;边缘计算网关还可以将处理后的数据上…

基于SpringBoot+Vue+uniapp的个人财务系统的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不…

linux下编译鸿蒙版curl、openssl

随着鸿蒙系统的正式发布日益临近&#xff0c;我们预见到在适配过程中&#xff0c;部分开发者可能需要编译特定版本的库以确保兼容性&#xff0c;比如编译curl-7.81和openssl-1.1.1m&#xff08;大家可以直接访问它们的官方网站下载所需的版本&#xff09;。 接下来&#xff0c…

k8s的部署

一、K8S简介 Kubernetes中文官网&#xff1a;Kubernetes GitHub&#xff1a;github.com/kubernetes/kubernetes Kubernetes简称为K8s&#xff0c;是用于自动部署、扩缩和管理容器化应用程序的开源系统&#xff0c;起源于Google 集群管理工具Borg。 Kubernetes集群组件逻辑图…

算法专题七: 分治归并

目录 1. 排序数组2. 交易逆序对的总数3. 计算右侧小于当前元素的个数4. 翻转对 1. 排序数组 算法思路: 本道题使用归并的思路进行排序, 先讲数组分为左右两个区间, 然后合并两个有序数组. class Solution {vector<int> tmp; public:vector<int> sortArray(vector&…

[含文档+PPT+源码等]精品基于php实现的原生微信小程序心理健康服务系统的设计与实现

基于PHP实现的原生微信小程序心理健康服务系统的设计与实现背景&#xff0c;可以从以下几个方面进行详细阐述&#xff1a; 一、技术背景 PHP技术&#xff1a; 广泛应用&#xff1a;PHP是一种开源的服务器端脚本语言&#xff0c;广泛用于Web开发领域。其丰富的函数库和灵活的语…

Redis-04 主从架构原理与搭建及主从优化方案

生产中使用Redis往往非单机部署&#xff0c;虽然根据前文已经对redis做了数据持久化处理&#xff0c;但是如果Redis服务宕机&#xff0c;所有的数据操作都将直接进入数据库&#xff0c;如果操作量很大&#xff0c;则相当于出现缓存穿透的现象。故生产中使用Redis一般采取【主从…

鸿蒙系统开发快速入门教程

一、开发环境准备 1. 下载并安装DevEco Studio DevEco Studio是华为官方提供的鸿蒙应用开发IDE&#xff0c;集成了开发、调试、模拟运行等功能&#xff0c;是鸿蒙开发的首要工具。 下载地址&#xff1a;前往华为开发者官网下载DevEco Studio。安装步骤&#xff1a;按照官方提…

类文件结构

文章目录 类文件结构字节码Class 文件结构总结魔数&#xff08;Magic Number&#xff09;Class 文件版本号&#xff08;Minor&Major Version&#xff09;常量池&#xff08;Constant Pool&#xff09;访问标志(Access Flags)当前类&#xff08;This Class&#xff09;、父类…

Luminar Neo v1.21.0.13934 图像编辑软件绿色便携版

skylum Luminar Neo 是一款由未来 AI 技术驱动的创意图像编辑器。并且支持微软Windows及苹果Mac OX系统&#xff0c;它使创作者能够将他们最大胆的想法变为现实并乐在其中。借助 Luminar Neo 领先的 AI 技术和灵活的工作流程&#xff0c;完成创意任务并获得专业品质的编辑结果。…

Python_函数式编程(内存管理机制)

将压缩文件减压&#xff0c;可以看到有很多文件&#xff0c;主要关心两个&#xff08;Include、Objects&#xff09;在Include目录下object.h中可以查看创建对象的结构体。 在创建对象时&#xff0c;每个对象至少内部4个值&#xff0c;PyObject结构体(上一个对象、下一个对象、…

Docker-Consul概述以及集群环境搭建

文章目录 一、Docker consul概述二、consul 部署1.consul服务器2.registrator服务器&#xff08;客户端&#xff09;2.consul-template&#xff08;在consul服务器&#xff09;3.consul 多节点 一、Docker consul概述 容器服务更新与发现&#xff1a;先发现再更新&#xff0c;…

51单片机快速入门之 LED点阵 结合74hc595 的应用 2024/10/16

51单片机快速入门之 LED点阵 结合74hc595 的应用 74HC595是一种常用的数字电路芯片&#xff0c;具有串行输入并行输出的功能。它主要由两个部分组成&#xff1a;一个8位的移位寄存器和一个8位的存储寄存器。数据通过串行输入管脚&#xff08;DS&#xff09;逐位输入&#xff0…

再Android10上实现检测AHD摄像头是否接入

项目有个需要&#xff0c;需要知道tp9951是否接入AHD摄像头 1&#xff0c;驱动层可以通过读取寄存器的值来检测是否接入AHD摄像头 tp9951_write_reg(0x40, 0x00); //select decoder page tp9951_write_reg(0x41, ch); val tp9951_read_reg(TP_INPUT_STATUS_REG);…

通过华为鲲鹏认证的软件产品如何助力信创产业

软件通过华为鲲鹏认证与信创产业有着密切的联系。鲲鹏认证是华为推动信创产业发展的一项重要举措&#xff0c;通过该认证&#xff0c;软件可以在华为的生态系统中实现更好的兼容性和性能优化&#xff0c;从而推动信创产业的全面发展和国产化替代。 鲲鹏认证的定义和重要性 鲲鹏…

python基于大数据的电影市场预测分析

一、摘要 智慧是改变生活和生产的一种来源&#xff0c;那么智慧的体现更大程度上是对于软件技术的改变。当今社会&#xff0c;好的思路&#xff0c;好的创新方式往往是改变人们生活的一种来源。最常见最直接的形式就是各种软件的创始思路&#xff0c;京东因为非典的流行才能够…

[全国/全省/全市]初赛知识点复习大汇总

目录 计算机结构与组成原理 计算机发展及应用 1、第一台电子计算机的诞生&#xff1a; ENIAC 2、第一台具有存储程序功能的计算机&#xff1a;EDVAC。 图灵 计算机发展阶段 世界上最快的超级计算机 计算机应用 计算机保护知识产权 计算机病毒 硬件系统的组成 概述 …