LeakCanary源码分析
来源:互联网 发布:数据库测试题 编辑:程序博客网 时间:2024/06/06 20:53
LeakCanary源码分析
LeakCanary是一个Android内存泄露自动分析工具,具有简单易用,结果可读性强,不仅适用于Android开发人员,也适用于测试人员使用。能快速提高软件质量。github地址:https://github.com/square/leakcanary
leakCanary包含3个模块leakcanary-android(leakcanary-android-no-op),leakcanary-watcher和leakcanary-analyzer。
leakcanary-android debug使用。负责启动内存泄露检测,给别的应用提供接口,包括启动和分析结果展示。
leakcanary-android-no-op 和 leakcanary-android一样,一般用在release版本中。
leakcanary-watcher 检测对象是否发生内存泄露,如果发生内存泄露则导出堆信息到本地文件中(*.hprof)
leakcanary-analyzer 从*.hprof文件中分析对象发生内存泄露原因,找出哪些对象强引用者监听对象。并将结果告诉leakcanary-android。
一. 流程图
二. 时序图
三. 重要类分析
1 LeakCanary: 入口类
/**启动对Activity内存泄露监听**/public static RefWatcher install(Application application);/**根据内存泄露分析结果,生成面向人的分析报告**/public static String leakInfo(Context context, HeapDump heapDump, AnalysisResult result,boolean detailed);
2 ActivityRefWatcher:这是一个代理类,主要功能是:注册ActivityLifecycleCallbacks回调,当Activity执行ondestroy()前,启动RefWatcher检测该Activity是否发生内存泄露。
3 RefWatcher:内存泄露检测核心类
/** * Watches the provided references and checks if it can be GCed. This method is non blocking, * the check is done on the {@link Executor} this {@link RefWatcher} has been constructed with. * * @param referenceName An logical identifier for the watched object. */ public void watch(Object watchedReference, String referenceName); /** *查看reference指向的对象是否发生内存泄露,如果发生泄露则启动HeapDump.dumpHeap()导出heap快照 */ void ensureGone(KeyedWeakReference reference, long watchStartNanoTime);
4 AndroidHeapDumper 实现了接口HeapDumper,导出当前内存快照到文件中。使用了Android自带的Debug类导出内存快照。
/** * 导出内存快照,保存到heapDumpFile文件中 */@Override public File dumpHeap() { File heapDumpFile = getHeapDumpFile(); boolean fileCreated; try { fileCreated = heapDumpFile.createNewFile(); } catch (IOException e) { cleanup(); CanaryLog.d(e, "Could not check if heap dump file exists"); return NO_DUMP; } Debug.dumpHprofData(heapDumpFile.getAbsolutePath()); return heapDumpFile; }
Debug.dumpHprofData(heapDumpFile.getAbsolutePath());
5 KeyedWeakReference: WeakReference的子类
String key;//用时间戳来唯一标识一个弱引用KeyedWeakReference(Object referent, String key, String name, ReferenceQueue<Object> referenceQueue) { super(checkNotNull(referent, "referent"), checkNotNull(referenceQueue, "referenceQueue")); this.key = checkNotNull(key, "key"); this.name = checkNotNull(name, "name"); }
构造函数传了一个ReferenceQueue给父类WeakReference。ReferenceQueue的作用是,当被引用的对象被JVM释放的时候会在该队列中生成一条记录(把该对象的弱引用放到该队列中),即:我们通过检查ReferenceQueue中是否存在我们关心的KeyedWeakReference来判断引用的对象是否被成功释放。代码如下:
KeyedWeakReference ref;boolean isLeak;while ((ref = (KeyedWeakReference) queue.poll()) != null) { retainedKeys.remove(ref.key); isLeak = !(retainedKeys.contains(ref.key));}if(retainedKeys.contains(ref.key)){ isLeak = true;}
6 ServiceHeapDumpListener:类存泄露监听器,当检测到发生内存,并且内存快照被导出到文件后,在该监听器中调用内存泄露分析工具。
7 HeapAnalyzerService:内存泄露分析Service,该类继承与IntentService,每个Intent在子线程中处理
8 HeapAnalyzer:类存泄露分析工具类
9 AbstractAnalysisResultService:负责接收内存泄露分析结果的Service
10 AnalysisResult:分析结果Model,结构如下:
/** True if a leak was found in the heap dump. */public final boolean leakFound;/** * True if {@link #leakFound} is true and the only path to the leaking reference is * through excluded references. Usually, that means you can safely ignore this report.* 如果为true,表示该泄露不是应用发生的,可以忽略 */public final boolean excludedLeak;/** * Class name of the object that leaked if {@link #leakFound} is true, null otherwise. * The class name format is the same as what would be returned by {@link Class#getName()}. */public final String className;/** * Shortest path to GC roots for the leaking object if {@link #leakFound} is true, null * otherwise. This can be used as a unique signature for the leak. */public final LeakTrace leakTrace;/** Null unless the analysis failed. */public final Throwable failure;/** * The number of bytes which would be freed if all references to the leaking object were * released. 0 if {@link #leakFound} is false. */public final long retainedHeapSize;/** Total time spent analyzing the heap. */public final long analysisDurationMs;
- LeakCanary源码分析
- LeakCanary源码分析
- LeakCanary源码分析
- LeakCanary源码分析
- LeakCanary源码分析第一讲
- 内存泄露检测神器 -- LeakCanary源码分析
- LeakCanary从入门到源码分析
- [源码]LeakCanary
- LeakCanary源码分析第二讲-RefWatcher详解
- LeakCanary源码分析第二讲-RefWatcher详解
- (4.2.39)内存泄漏检测LeakCanary源码分析
- 《android源码分析系列》LeakCanary- 如何检测 Activity 是否泄漏
- LeakCanary源码学习
- LeakCanary框架源码解析
- LeakCanary分析内存泄漏
- LeakCanary原理分析
- Android-LeakCanary原理分析
- 性能分析-内存分析leakcanary
- AppWidget运用实例
- 哈希表详解
- network2
- IP动态选路和最短路算法
- leetcode 18.4Sum
- LeakCanary源码分析
- vector 释放内存 swap
- Android Sharedpreference学习
- 转眼就快过去了一年半
- 第一次做二级联动,没有用到对象与二维数组(笨方法,思路简单)
- C语言中的static 详细分析
- JavaScript实现图片轮播
- Problem q
- 两篇文章掌握Python语法和内置函数功能(第二篇)