Android-LeakCanary原理分析
来源:互联网 发布:mac air换外壳 编辑:程序博客网 时间:2024/06/05 19:13
介绍
LeakCanary项目是为Java&Android开发提供的一个自动检测内存泄漏的工具,现在很多项目都在引入来提高代码质量,减少不必要的内存泄漏。
核心方法流程图
初始化流程
通过以下方法,将内存泄露框架添加到App中。
//在Application中添加内存监控框架LeakCanary.install(this);
添加到App中,实际上就是构造了一个RefWatcher对象,并且设置Activity生命周期的监听。当Activity被销毁的时候,调用内存泄露框架进行监控。
//实现方法public static RefWatcher install(Application application) { return refWatcher(application).listenerServiceClass(DisplayLeakService.class) .excludedRefs(AndroidExcludedRefs.createAppDefaults().build()) .buildAndInstall();}//生产AndroidRefWatcherBuilder内存泄露监控对象构造器public static AndroidRefWatcherBuilder refWatcher(Context context) { return new AndroidRefWatcherBuilder(context);}
在buildAndInstall()方法中,设置Activity生命周期的监听,并监控Acitivty内存泄露
public RefWatcher buildAndInstall() { //构造器生产RefWatcher对象 RefWatcher refWatcher = build(); if (refWatcher != DISABLED) { //添加对Activity生命周期的监听 ActivityRefWatcher.install((Application) context, refWatcher); } return refWatcher; } //ActivityRefWatcher.install()方法实现 public static void install(Application application, RefWatcher refWatcher) { new ActivityRefWatcher(application, refWatcher).watchActivities(); } public void watchActivities() { //注册Application生命周期监听 application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { } @Override public void onActivityStarted(Activity activity) { } @Override public void onActivityResumed(Activity activity) { } @Override public void onActivityPaused(Activity activity) { } @Override public void onActivityStopped(Activity activity) { } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { } @Override public void onActivityDestroyed(Activity activity) { //Activity.onDestory()回调时,被触发 ActivityRefWatcher.this.onActivityDestroyed(activity); } }); }
检查内存泄露
通过调用watch()方法,触发内存泄露检查。
/** * 检测提供的(watchedReference)对象,是否存在内存泄露问题 * @param watchedReference 被检测的对象 * @param referenceName 引用名 */ public void watch(Object watchedReference, String referenceName) { if (this == DISABLED) { return; } //判空 checkNotNull(watchedReference, "watchedReference"); checkNotNull(referenceName, "referenceName"); //开始检测内存泄漏的时间 final long watchStartNanoTime = System.nanoTime(); //生成检测对象的key String key = UUID.randomUUID().toString(); //保存检测对象的key retainedKeys.add(key); //生成弱引用 final KeyedWeakReference reference = new KeyedWeakReference(watchedReference, key, referenceName, queue); //异步检测对象是否内存泄露 ensureGoneAsync(watchStartNanoTime, reference); } //异步检测对象是否内存泄露 private void ensureGoneAsync(final long watchStartNanoTime, final KeyedWeakReference reference) { watchExecutor.execute(new Retryable() { @Override public Retryable.Result run() { return ensureGone(reference, watchStartNanoTime); } }); } //真正的内存泄露检测方法 Retryable.Result ensureGone(final KeyedWeakReference reference, final long watchStartNanoTime) { long gcStartNanoTime = System.nanoTime(); long watchDurationMs = NANOSECONDS.toMillis(gcStartNanoTime - watchStartNanoTime); //清除此时已经到ReferenceQueue中的弱引用 removeWeaklyReachableReferences(); // (1)如果当前检测的对象已经弱可达,那么说明对象已经不会泄漏 if (gone(reference)) { return DONE; } //如果当前检测对象还没有改变其可达状态,GC() gcTrigger.runGc(); //再次判断对象有没有进入队列 removeWeaklyReachableReferences(); //(2)如果此时还没有检测到入队列,那么有可能这个对象已经泄漏 if (!gone(reference)) { //进入第二部,dump内存,分析内存快照 //该部分,暂未分析 long startDumpHeap = System.nanoTime(); long gcDurationMs = NANOSECONDS.toMillis(startDumpHeap - gcStartNanoTime); File heapDumpFile = heapDumper.dumpHeap(); long heapDumpDurationMs = NANOSECONDS.toMillis(System.nanoTime() - startDumpHeap); //处理分析结果 heapdumpListener.analyze( new HeapDump(heapDumpFile, reference.key, reference.name, excludedRefs, watchDurationMs, gcDurationMs, heapDumpDurationMs)); } return DONE; } //判断检测对象,是否已经被释放 private boolean gone(KeyedWeakReference reference) { return !retainedKeys.contains(reference.key); } //如果为弱引用,在对象被释放的时候,就会将对象添加到ReferenceQueue中 //通过调用ReferenceQueue.poll()来将已经释放的对象从map中移除 private void removeWeaklyReachableReferences() { KeyedWeakReference ref; while ((ref = (KeyedWeakReference) queue.poll()) != null) { retainedKeys.remove(ref.key); } }
自动检测Activity内存泄露
由于上面的分析可得,在Activity.onDestory()回调的时候,会触发onActivityDestroyed()监听方法,下面是此方法内容
void onActivityDestroyed(Activity activity) { refWatcher.watch(activity);}
也就是说,在Activity被销毁的时候,会自动检测此Activity是否存在内存泄露问题。
内存泄露框架划分
内存泄露框架存在三个模块,划分结构如下:
- leakcanary-watcher: 这是一个通用的内存检测器,对外提供一个 RefWatcher#watch(Object watchedReference),可以看出,它不仅能够检测 Activity,还能监测任意常规的 Java Object 的泄漏情况。
- leakcanary-android: 这个 module 是与 Android 世界的接入点,用来专门监测 Activity 的泄漏情况,内部使用了 application#registerActivityLifecycleCallbacks 方法来监听 onDestory 事件,然后利用 leakcanary-watcher 来进行弱引用+手动 GC 机制进行监控。
- leakcanary-analyzer: 这个 module 提供了 HeapAnalyzer,用来对 dump 出来的内存进行分析并返回内存分析结果 AnalysisResult,内部包含了泄漏发生的路径等信息供开发者寻找定位。
阅读全文
0 0
- Android-LeakCanary原理分析
- LeakCanary原理分析
- LeakCanary 流程及原理分析
- leakcanary原理分析与AppsFly内存泄漏
- Android AndroidStudio MAT LeakCanary 内存分析之 LeakCanary
- leakcanary:原理
- Android 内存泄漏分析工具LeakCanary
- Android内存泄露分析工具LeakCanary
- android 内存分析工具leakcanary接入
- Android LeakCanary
- Android 内存泄露检测工具 LeakCanary 的监控原理
- android专题研究--内存泄漏(leakcanary用法与实现原理)
- LeakCanary原理解析
- LeakCanary原理解析
- LeakCanary 原理浅析
- Android内存泄漏分析及实践(三)-leakCanary
- Android AndroidStudio MAT LeakCanary 内存分析之 初识内存泄漏
- Android AndroidStudio MAT LeakCanary 内存分析之 DDMS+MAT
- [HDU 6122] Color the chessboard
- 基于javaweb的客户信息管理系统搭建
- MOS管的工作原理浅显易懂
- Linux学习笔记(三)------文件命令
- 枚举和注解(Enum and Annotation)
- Android-LeakCanary原理分析
- 网易2018年校招
- linux中的集线器、交换机、路由器及组网
- HTTP Error 500.19
- Linux管理杂记
- 架构师成长之路
- 理解 Android Build 系统
- maven 开发布署
- 《deep learning》学习笔记(5)——机器学习基础