LeakCanary
应用稳定性和性能是非常重要的,LeakCanary作为这方面的工具,技术原理深厚,值得一探。 LeakCanary检测缩小内存泄漏错点,主要工作原理过程
- 检测保留的对象。
- 倾倒堆。
- 分析堆。
- 对泄漏进行分类。
初级核心思路,迭代演化重构,以至于庞杂
1、概览
整个工程模块结构设计:
leakcanary-repo(5(29))
leakcanary(11)
leakcanary-android(没有源码,主要集成依赖)
leakcanary-android-core
leakcanary-android-instrumentation
leakcanary-android-process
leakcanary-android-release
leakcanary-android-startup
leakcanary-android-utils
leakcanary-app[apk]
leakcanary-app-aidl
leakcanary-app-service
leakcanary-deobfuscation-gradle-plugin[jar]
object-watcher(6)
object-watcher[jar]
object-watcher-android
object-watcher-android-androidx
object-watcher-android-core
object-watcher-android-startup
object-watcher-android-support-fragments
plumber(3)
plumber-android
plumber-android-core
plumber-android-startup
samples(1)
leakcanary-android-sample[apk]
shark(6+2)
shark[jar]
shark-android[jar]
shark-cli[jar]
shark-graph[jar]
shark-hprof[jar]
shark-hprof-test[jar]
shark-log[jar]
shark-test[jar]
2、模块依赖关系
leakcanary-repo(5(29))
leakcanary(11)
leakcanary-android(门面aar,没有代码,仅集成核心依赖)
api projects.leakcanary.leakcanaryAndroidCore
api projects.objectWatcher.objectWatcherAndroid
implementation projects.plumber.plumberAndroid
implementation libs.kotlin.stdlib
leakcanary-android-core(核心ui)
api projects.shark.sharkAndroid
api projects.objectWatcher.objectWatcherAndroidCore
api projects.objectWatcher.objectWatcherAndroidAndroidx
api projects.objectWatcher.objectWatcherAndroidSupportFragments
implementation libs.kotlin.stdlib
compileOnly libs.androidX.work.runtime
compileOnly libs.androidX.work.multiprocess
leakcanary-android-instrumentation(测试)
api projects.leakcanary.leakcanaryAndroidCore
leakcanary-android-process(独立进程分析)
api projects.shark.sharkLog
api projects.objectWatcher.objectWatcherAndroidCore
implementation libs.kotlin.stdlib
implementation libs.androidX.work.multiprocess
leakcanary-android-release(后台锁屏任务分析拦截器)
api projects.shark.sharkAndroid
api projects.leakcanary.leakcanaryAndroidUtils
implementation libs.kotlin.stdlib
implementation libs.okio2
leakcanary-android-startup(门面aar,没有代码,androidx.startup.Initializer方式初始化)
api projects.leakcanary.leakcanaryAndroidCore
implementation projects.objectWatcher.objectWatcherAndroidStartup
implementation projects.plumber.plumberAndroidStartup
leakcanary-android-utils(几个工具类)
api projects.shark.sharkLog
implementation libs.kotlin.stdlib
leakcanary-app(应用)
implementation projects.leakcanary.leakcanaryAppAidl
implementation projects.leakcanary.leakcanaryAndroid
leakcanary-app-aidl(跨进程传输分析数据接口)
implementation libs.kotlin.stdlib
implementation projects.shark.shark
leakcanary-app-service(带存储权限访问的跨进程传输分析数据的客户端)
implementation projects.leakcanary.leakcanaryAppAidl
implementation projects.shark.shark
leakcanary-deobfuscation-gradle-plugin(插件)
implementation libs.kotlin.stdlib
implementation libs.gradlePlugin.kotlin
implementation libs.gradlePlugin.android
compileOnly gradleApi()
object-watcher(6)
object-watcher(给对象附加观察属性--引用情况)
implementation libs.kotlin.stdlib
api projects.shark.sharkLog
object-watcher-android(借助cp自动加载,安装对象观察核心)
api projects.objectWatcher.objectWatcherAndroidCore
object-watcher-android-androidx(object-watcher-android-core之androidx兼容)
api projects.objectWatcher.objectWatcherAndroidCore
implementation libs.kotlin.stdlib
compileOnly libs.androidX.fragment
object-watcher-android-core(提供默认的4类对象的观察)
api projects.objectWatcher.objectWatcher
api projects.leakcanary.leakcanaryAndroidUtils
implementation libs.curtains
implementation libs.kotlin.stdlib
object-watcher-android-startup(androidx.startup.Initializer,安装对象观察核心)
api projects.objectWatcher.objectWatcherAndroidCore
implementation libs.androidX.startup
object-watcher-android-support-fragments(object-watcher-android-core之support兼容,已删除整个模块)
api projects.objectWatcher.objectWatcherAndroidCore
implementation libs.kotlin.stdlib
compileOnly libs.androidSupport
plumber(3)
plumber-android(借助cp,安装框架库泄漏修复)
api projects.plumber.plumberAndroidCore
implementation libs.kotlin.stdlib
plumber-android-core(枚举已知漏洞修复方案)
api projects.shark.sharkLog
api projects.leakcanary.leakcanaryAndroidUtils
implementation libs.kotlin.stdlib
implementation libs.curtains
compileOnly libs.androidX.fragment
plumber-android-startup(androidx.startup.Initializer方式初始化,安装框架库泄漏修复)
api projects.plumber.plumberAndroidCore
implementation libs.kotlin.stdlib
implementation libs.androidX.startup
samples(1)
leakcanary-android-sample
debugImplementation projects.leakcanary.leakcanaryAndroid
debugImplementation projects.leakcanary.leakcanaryAppService
debugImplementation projects.leakcanary.leakcanaryAndroidStartup
debugImplementation projects.leakcanary.leakcanaryAndroidProcess
releaseImplementation projects.leakcanary.leakcanaryAndroidRelease
releaseImplementation projects.objectWatcher.objectWatcherAndroid
implementation libs.kotlin.stdlib
shark(6+2)
shark(生成对分析报告)
api projects.shark.sharkGraph
implementation libs.kotlin.stdlib
implementation libs.okio2
shark-android(生成安卓量身定制的对分析报告)
api projects.shark.shark
implementation libs.kotlin.stdlib
shark-cli(shark命令行界面使你可以直接从pc分析安卓设备上应用程序产生的堆)
api projects.shark.sharkAndroid
implementation libs.clikt
implementation libs.neo4j
implementation libs.jline
implementation libs.kotlin.stdlib
shark-graph(导航堆对象图)
api projects.shark.sharkHprof
implementation libs.kotlin.stdlib
implementation libs.okio2
shark-hprof(hprof文件中的记录读写)
api projects.shark.sharkLog
implementation libs.kotlin.stdlib
compileOnly libs.okio1
shark-hprof-test(写辅助类)
implementation libs.kotlin.stdlib
implementation libs.junit
implementation libs.okio2
implementation projects.shark.sharkHprof
shark-log(日志接口)
implementation libs.kotlin.stdlib
shark-test(测试堆转储)
implementation libs.kotlin.stdlib
implementation libs.assertjCore
implementation libs.junit
可以看到项目有多条依赖线,主要的app依赖,startup依赖,测试依赖,等。串一下对整个工程不留太多遗漏。
3、模块业务实现
leakcanary-repo(5(29))
leakcanary(11)
leakcanary-android(门面aar,没有代码,仅集成核心依赖)
不提供代码的目的需要思考一下
leakcanary-android-core(核心ui)
LeakCanaryFileProvider对于hprof文件存储位置权限读写兼容
LeakActivity主界面,tab以及Screen泛化切换,可以接受外部Uri方式的hprof文件,发dump事件触发泄漏分析或通知展示等。
HeapDumpsScreen中间HeapDumps页面,
HeapAnalysisTable堆分析泄漏记录表
AndroidDebugHeapAnalyzer分析hprof文件得到泄漏记录,插入HeapAnalysisTable表。分析得到泄漏记录使用shark族库,具体看。
HeapDumpScreen多类型列表,顶部html可点击标签,中间泄漏数量,下部泄漏列表,直接HeapAnalysisTable查询泄漏记录展示列表
LeakScreen\&DisplayLeakAdapter展示具体泄漏位置,将泄漏信息展示成html文本拼接
NotificationReceiver接受堆转储广播,获取堆转储文件
HeapDumpTrigger采集堆转储文件,展示泄漏通知,发送获取堆转储文件状态事件
AndroidDebugHeapDumper采用Debug.dumpHprofData获取堆转储文件
RemoteWorkManagerHeapAnalyzer\&RemoteHeapAnalyzerWorker
通过LeakCanary.Config.eventListeners接受堆转储完成事件结合leakcanary-android-process的RemoteLeakCanaryWorkerService达到独立进程分析堆转储
leakcanary-android-instrumentation(测试)
leakcanary-android-process(独立进程初始化及分析)
leakcanary-android-release(后台锁屏任务分析拦截器)
leakcanary-android-startup(门面aar,没有代码,androidx.startup.Initializer方式初始化)
leakcanary-android-utils(几个工具类)
leakcanary-app(应用)
leakcanary-app-aidl(跨进程传输分析数据接口)
leakcanary-app-service(带存储权限访问的跨进程传输分析数据的客户端)
leakcanary-deobfuscation-gradle-plugin(插件)
object-watcher(6)
object-watcher(给对象附加观察属性--引用情况)
1. Clock:这个类的主要作用是提供一个可配置的时钟服务,用于 Android 应用测试中加速和模拟时间间隔和时间戳。
2. GcTrigger:这个类提供了与 System.gc() 相关的便捷工具方法,用于在可能的情况下快速启动垃圾回收并尽早清理未使用的内存空间。
3. KeyedWeakReference:这个类提供了一个对对象进行弱引用的封装,可以根据键值来存储和管理这些未使用的对象,以便于内存管理。
4. ObjectWatcher:这个类用于监控 Java 对象的引用计数并生成日志信息,以便检测应用程序中可能存在的内存泄漏或过度使用。
5. OnObjectRetainedListener:这个接口是 ObjectWatcher 的回调接口,用于处理内存对象的保留和释放事件,以便于进行相应的处理和分析。
6. ReachabilityWatcher:这个类可以用于监控和处理对象的可达性变化,以及相应的对象引用计数和生命周期变化。
object-watcher-android-core(提供默认的4类对象的观察)
- AndroidOFragmentDestroyWatcher:用于在Android O及以上版本中检测Fragment的内存泄漏问题。
- Applications.kt:是否可以调试
- LeakCanaryDelegate:用于处理内存泄漏检测的代理类。
- ActivityWatcher:用于检测Activity的内存泄漏问题。
- AppWatcher:用于监测整个应用程序中的内存泄漏问题。
- FragmentAndViewModelWatcher:用于检测Fragment和ViewModel中的内存泄漏问题。
- InstallableWatcher:用于检测可安装组件的内存泄漏问题,例如BroadcastReceiver和Service。
- RootViewWatcher:用于检测根视图(RootView)中的内存泄漏问题。
- ServiceWatcher:用于检测Service的内存泄漏问题。
object-watcher-android-startup(androidx.startup.Initializer,安装对象观察核心)
object-watcher-android-support-fragments(object-watcher-android-core之support兼容,已删除整个模块)
plumber(3)
plumber-android(借助cp,安装框架库泄漏修复)
plumber-android-core(枚举已知漏洞修复方案)
plumber-android-startup(androidx.startup.Initializer方式初始化,安装框架库泄漏修复)
samples(1)
leakcanary-android-sample
shark(6+2)
shark(生成对分析报告)
HeapAnalyzer核心类,分析堆转储文件得到HeapAnalysis,供AndroidDebugHeapAnalyzer|InstrumentationHeapAnalyzer| RealHeapAnalysisJob|AnalyzeCommand|InteractiveCommand调用,ui,测试框架,命令行,子进程
HeapAnalysis分析结果:HeapAnalysis|HeapAnalysisFailure|HeapAnalysisSuccess|Leak|LibraryLeak|ApplicationLeak
ActualMatchingReferenceReaderFactory用于创建匹配引用阅读器,其作用是实现匹配引用阅读器的创建和配置
AndroidNativeSizeMapper用于映射Android原生(native)对象的工具
AppSingletonInspector一种用于检测Android应用程序中单例(Singleton)对象的工具
FilteringLeakingObjectFinder用于查找内存泄漏对象并排除一些不需要的对象。
ReferencePathNode是指在Java虚拟机堆内存分析中,表示对象引用路径的节点
GcRootProvider接口
GcRootReference垃圾回收根引用
HeapAnalysisException异常
KeyedWeakReferenceFinder查找 Java 应用程序中的弱引用泄漏对象
LeakingObjectFinder用于查找 Java 应用程序中的内存泄漏对象FilteringLeakingObjectFinder|KeyedWeakReferenceFinder|ArraySetFakeLeakingObjectFinder
LeakNodeStatus
LeaksAndUnreachableObjects
LeakTrace描述 Java 应用程序中的内存泄漏问题。
LeakTraceObject包含了描述内存泄漏对象的各种信息,例如对象的类型、对象的大小、对象的引用关系等。它还可以描述内存泄漏的原因和场景。
LeakTracer通过分析 HeapDump 文件(堆转储文件),找到可能出现内存泄漏的对象。在检测过程中,LeakTracer 会遍历 HeapDump 文件中的所有对象,并根据对象之间的引用关系判断哪些对象可能出现了内存泄漏。如果出现了内存泄漏,LeakTracer 将记录下出现内存泄漏的对象,并提供相关的信息,例如对象的类型、对象的大小、对象的引用关系等。
LeakTraceReference表示内存泄漏问题中的引用关系
MatchingGcRootProvider可以根据特定的条件查找堆中特定类型的对象,并将这些对象与它们的GC Roots匹配。
MetadataExtractor,用于提取Java堆转储文件(HeapDump)中的元数据信息。在Java应用程序中,元数据信息包括对象的类型、大小、地址等。AndroidMetadataExtractor
ObjectDominators支配树(Dominator Tree)是指根据对象支配者(Dominators)而建立起来的一棵树形结构。在Java应用程序中,支配树表示了对象之间的支配关系,使得我们能够更加清楚地了解对象之间的引用关系,从而分析和解决内存泄漏等问题。
ObjectInspector
ObjectInspectors枚举了jdk几种类的描述:弱引用、类加载器、类、匿名类、线程
ObjectReporter对象是否泄漏的报告,含原因
OnAnalysisProgressListener堆转储文件内存泄漏分析步骤进度回调,HeapAnalyzer
RealLeakTracerFactory,RealLeakTracerFactory 可以帮助我们创建 LeakTracer 对象,并提供检测内存泄漏的功能。
Reference引用
ReferenceLocationType枚举引用类型
ReferenceMatcherJava中的垃圾收集机制(Garbage Collection,GC),并提供了一种方便的方式,帮助开发者根据不同的引用策略,对对象进行垃圾回收。
ReferencePattern引用匹配,垃圾回收的模式匹配方法。ReferencePattern|JavaLocalPattern|StaticFieldPattern|InstanceFieldPattern|NativeGlobalVariablePattern
ReferenceReader接口,用于实现垃圾回收器中的引用读取器。定义了一个read()方法,用于遍历堆对象中的所有引用。具体来说,read()方法可以读取堆对象中包含的所有弱引用、软引用、虚引用、普通引用等引用信息,并将其作为Reference对象返回。通过遍历每个堆对象中的所有引用,程序员可以进行引用匹配并进行相应的垃圾回收操作。
AndroidReferenceReaderFactory的作用是创建并配置一个 Android 引用阅读器。通过使用不同的配置选项,可以创建不同类型的 Android 引用阅读器,以满足特定的需求。
ChainingInstanceReferenceReader是一种链式实例引用读取器
AndroidReferenceReaders枚举用于读取Android应用程序运行时对象引用关系的工具集合
ApacheHarmonyInstanceRefReaders提供了创建 Apache Harmony 实例引用阅读器的方法
FieldInstanceReferenceReader主要用于内存泄漏检测期间分析对象引用关系,将实例化对象与其字段引用关系连接起来
FieldIdReader是一种用于读取Java类字段信息的工具。它可以帮助开发人员确定一个类的所有字段和它们的相关信息,例如字段的名称、类型、修饰符等。
ObjectArrayReferenceReader用于读取Java堆转储文件(HeapDump)中的对象数组引用
ClassReferenceReader提供了创建 Java 类引用阅读器的方
JavaLocalReferenceReader读取当前 Java 方法的本地引用器,将当前方法中临时创建的对象与其引用关系连接起来
ThreadObjects可以让开发人员访问和修改线程局部存储中的变量。
JavaFrames是指在Java虚拟机堆栈分析中,表示Java方法调用链的框架。它是在Java虚拟机中执行程序时,维护程序状态和方法调用链的关键数据结构。在Java虚拟机堆栈中,每个线程都有自己的JavaFrames堆栈,其可以记录该线程执行的每个方法的信息,包括方法名、参数值、局部变量等。每一次方法调用,Java虚拟机会在栈上创建一个新的JavaFrame对象,保存该方法的信息,并将其推送到栈顶。当方法运行完成后,JavaFrame会出栈,返回调用方法,在方法执行过程中对JavaFrame的操作,可以通过Java虚拟机堆栈分析工具进行展示和分析。
OpenJdkInstanceRefReaders枚举jdk几种常见集合列表的引用分析
DelegatingObjectReferenceReader通过委托方式实现 ObjectReference 的解析和读取,具有较高的灵活性和扩展性。4类节点的读取
ShortestPathFinder用于搜索最短路径的算法实现
PathFindingResults寻路算法的结果,引用路径及支配节点树
PrioritizingShortestPathFinder实现了 Dijkstra 算法,是一种广泛使用的最短路径查找算法。该算法通过维护一个节点集合以及每个节点到起点的最短距离,从而逐步遍历所有节点并计算出最短路径。
Dominators一种用于计算支配器的算法
DominatorTree是一个重要的数据结构,可以用于程序分析和优化,例如在循环展开、指针分析和内联函数等方面的应用。
VirtualizingMatchingReferenceReaderFactoryr是一种特殊的引用读取器,它可以仅遍历与给定模板匹配的对象工厂
InternalSharedExpanderHelpers|InternalSharkCollectionsHelper可以帮助开发人员在Shark框架中进行集合操作,例如在集合中添加或删除元素,查找集合中的元素,按排序规则对集合进行排序等。
shark-android(生成安卓量身定制的对分析报告)
AndroidBuildMirror系统sdk版本信息
AndroidExtensions系统表示hash码
AndroidMetadataExtractor元数据
AndroidObjectInspectors枚举方式AOSP和库特有的重要的对象泄漏分析
AndroidReferenceMatchers枚举已知的框架泄漏点匹配条件(类名,字段名,版本,描述)
AndroidResourceIdNames资源id与name,用于分析资源泄漏
AndroidServices进程中service的id
shark-cli(shark命令行界面使你可以直接从pc分析安卓设备上应用程序产生的堆)
shark-graph(导航堆对象图)
HeapGraph堆对象图(多棵树)5中节点的数量及列表,提供id、name方式查询节点
HeapObject|HeapClass|HeapInstance|HeapObjectArray|HeapPrimitiveArray堆对象图节点5种类型
HeapField对象属性,可能是HeapObject的几种类型
HeapValue值,基本类型以及对象类型
ClassFieldsReader从IndexedClass读取FieldRecord
FieldValuesReader从FieldRecord读取基本类型的值
HprofHeapGraph堆快照的对象引用关系图的实现
HprofInMemoryIndex堆对象图数据节点索引
shark-hprof(hprof文件中的记录读写)
ByteArraySourceProvider字节数组随机读取
ConstantMemoryMetricsDualSourceProvider低内存随机读取
DualSourceProvider随机读取流
FileSourceProvider文件随机读取
GcRoot垃圾回收根对象,分类比较多
HprofDeobfuscator是一个用于解密 HPROF 文件的工具,能够消除应用程序代码混淆对内存调试造成的影响
HprofHeader堆转储文件的元数据或者头
HprofPrimitiveArrayStripper是一个用于去除 HPROF 文件中基本数据类型数组信息的工具。
HprofRecord 文件中记录数据的基本单位,代表了 Heap(堆)中的一个 Java 对象或者其他数据结构,如线程栈、本地变量等。扩展种类比较多。
HprofRecordReader读取堆转储文件中各种HprofRecord记录
HprofRecordTag枚举HprofRecord的各种类型
HprofVersion是 HPROF 文件的版本号,在 HPROF 文件的开头标识了 HPROF 文件的版本信息
HprofWriter是一个用于生成 HPROF 文件的工具
OnHprofRecordListener读取解析记录回调
OnHprofRecordTagListener堆去解析记录类型回调
PrimitiveType基础数据类型
ProguardMapping记录了混淆前和混淆后的类、方法、字段之间的映射关系。
ProguardMappingReader可以方便地读取 Proguard Mapping 文件,并将其中的映射关系提取出来,方便进行代码调试和分析。
RandomAccessHprofReader
RandomAccessSource是一种可以随机访问数据源的抽象,它可以通过指定偏移量和长度的方式读取数据源中的特定部分。
RandomAccessSourceProvider是一个用于提供随机访问的数据源的工具。它可以方便地读取、操作和处理大型二进制数据,如图片和视频等文件。
StreamingHprofReader与 RandomAccessHprofReader 不同的是,StreamingHprofReader 是一种基于流的 HPROF 文件解析器,它可以对 HPROF 文件进行逐字节解析,不需要全部读入内存。
StreamingRecordReaderAdapter是一种可以将流式数据转换为记录形式的工具
StreamingSourceProvider读取流接口
ThrowingCancelableFileSourceProvider是一个实现 RandomAccessSourceProvider 接口,用于提供随机访问文件数据源的工具。与 CancelableFileSourceProvider 不同的是,ThrowingCancelableFileSourceProvider 在读取文件时,当遇到读取错误时会抛出异常。
ValueHolder是一种数据容器,用于存储在某个上下文中的值。基本类型以及对象引用
shark-hprof-test(写辅助类)
shark-log(日志接口)
shark-test(测试堆转储)
、、、
参考文档
(42条消息) 构造Dominator Tree以及Dominator Frontier_dominatortree_电影旅行敲代码的博客-CSDN博客
(42条消息) Leakcanary - hprof分析库shark 源码分析_shark源码分析_stone_cold_cool的博客-CSDN博客
(42条消息) 支配节点树及其构建算法 Dominator-tree and its Construction Algorithms_节点的支配节点_loongknown的博客-CSDN博客
LeakCanary 你真的了解么?看看这些高级用法 - 掘金 (juejin.cn)
(42条消息) android中hprof文件分析_android hprof_HankingHu的博客-CSDN博客
使用shark库解析Hprof文件(一) - 掘金 (juejin.cn)
Android 性能监控框架 Matrix(3)Hprof 文件分析 - 掘金 (juejin.cn)
使用shark库解析Hprof文件(一) - 掘金 (juejin.cn)