Android内存泄漏检测工具:LeakCanary

简介: 版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/79582082 一、简介LeakCanary是一个Square开源的内存泄漏分析工具,如果检测到某个activity有内存泄漏,LeakCanary就会自动显示一个通知。
版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csdn.net/NoMasp/article/details/79582082

一、简介

LeakCanary是一个Square开源的内存泄漏分析工具,如果检测到某个activity有内存泄漏,LeakCanary就会自动显示一个通知。

二、如何使用

2.1)在app下的build.gradle中加入以下依赖

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

2.2)在Application类中进行初始化,可以直接检测Activity的内存泄露情况

public class ExampleApplication extends Application {
    @Override public void onCreate() { 
        super.onCreate(); 
        LeakCanary.install(this);
    }
 }

2.3)需要检测更多object时,可以通过RefWatcher

public class ExApplication extends Application {
    private RefWatcher mRefWatcher;
    @Override
    public void onCreate() {
        super.onCreate();
        mRefWatcher = setupLeakCanary();
    }
    private RefWatcher setupLeakCanary() {
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return RefWatcher.DISABLED;
        }
        return LeakCanary.install(this);
    }
    public static RefWatcher getRefWatcher(Context context) {
        ExApplication leakApplication = (ExApplication) context.getApplicationContext();
        return leakApplication.mRefWatcher;
    }
}

ExApplication.getRefWatcher(this).watch(obj);
// RefWatcher是线程安全的,可以从任何线程调用,但obj不能为null。

三、如何实现

3.1)在2.2中 直接install后即可检测Activity的原因

public static RefWatcher install(Application application) {
  return refWatcher(application).listenerServiceClass(DisplayLeakService.class)
      .excludedRefs(AndroidExcludedRefs.createAppDefaults().build())
      .buildAndInstall();
}

在install的 buildAndInstall 方法中会根据application来创建ActivityRefWatch,以检测Activity的生命周期,在onActivityDestroyed时,依然是使用refWatcher.wath(activity),所以其实是一样的。

3.2)KeyedWeakReference 继承自 WeakReference,同时还会针对每个引用记录唯一的key。

3.3)DISABLED的定义:
public static final RefWatcher DISABLED = new RefWatcherBuilder<>().build();
debug中使用的源码在 leakcanary-android,release中使用的源码在 leakcanary-android-no-op. DISABLED中返回的方法

3.4)LeakCanary实际上就是在本机自动做Heap dump,然后对生成的hprof文件进行分析,进行结果展示,和手工分析MAT步骤基本一致。

  1. RefWatcher.watch() 方法中根据要监控的对象创建一个KeyedWeakReference
  2. 2.在后台线程中检查引用是否被清除,如果没有,则调用GC
  3. 如果引用仍未被清除,说明内存泄露了,则导出.hprof文件到app的文件系统目录下
  4. HeapAnalyzerService启动单独的进程,HeapAnalyzer使用HAHA来解析.hprof文件
  5. HeapAnalyzer根据唯一的reference key查找 KeyedWeakReference定位内存泄露
  6. HeapAnalyzer 计算 KeyedWeakReference 所引用对象的最短强引用路径,并确定是否泄露,构建导致泄露的对象引用链
  7. 将引用链传递回运行在APP进程中的 DisplayLeakService,并以通知的形式展示出来

四、哪些需要监控

Activity、Fragment、Bitmap、其他具有生命周期的对象、可能持有较大内存占用的对象等。

五、何时进行监控

内存泄漏就是某个对象在理应释放的时候却被其他对象持有,而没有被释放,因此造成内存泄漏。因此监控需要放在对象(很快)被释放的时候,比如Activity和Fragment的onDestroy方法中。

六、解决方案

  1. 使用Application的Context而不是Activity的
  2. 使用弱引用或软引用(弱引用:GC会来决定引用的对象何时回收并将对象从内存中移除,软引用:停留在内存的时间比弱引用较长,当内存不足时GC才会回收软引用可到达的对象,因此可以作为缓冲)
  3. 手动置空,解除引用关系
  4. 将内部类设置为static,因为非静态内部类会隐式持有外部类实例的引用
  5. 注册和取消注册首位成对,在对象合适的生命周期进行
  6. 资源性对象(比如Cursor、File等)往往都做了一些缓冲,在不使用时应该及时关闭,以便他们的缓冲对象能够被及时回收。这些缓冲不仅存在于Java虚拟机内,还存在于虚拟机外,如果我们仅仅将它的引用设置为null而不关闭它们,往往会造成内存泄漏。

七、注意事项

  1. release版本不能带,因为会带来更多的分析计算影响CPU等资源的占用
  2. 检测比较慢,涉及到I/O和大量计算,通常在20s~1min之间,和当前CPU占用情况有关
  3. 每次只能显示一条内存了泄漏的消息
  4. 如果最近有一个新的heap dump file被创建,还在分析中,那么就会在稍后再进行dump

八、其他工具

9.1)Lint (是Android Studio自带的静态代码分析工具,Analyze -> Inspect Code)
可以直接对单个文件或整个模块进行分析,以性能为例:

Android Lint: Performance
Do not place Android context classes in static fields; this is a memory leak (and also breaks instant Run)

九、LeakCanary源码

github.com/square/leakcanary

目录
相关文章
|
1月前
|
存储 前端开发 Java
Android MVVM架构模式下如何避免内存泄漏
Android采用MVVM架构开发项目,如何避免内存泄漏风险?怎样避免内存泄漏?
89 1
|
9天前
|
Android开发 开发者
Android性能优化——内存管理的艺术
Android性能优化——内存管理的艺术
|
1月前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
49 2
|
2月前
|
Java 测试技术 Android开发
Android性能测试——发现和定位内存泄露和卡顿
本文详细介绍了Android应用性能测试中的内存泄漏与卡顿问题及其解决方案。首先,文章描述了使用MAT工具定位内存泄漏的具体步骤,并通过实例展示了如何分析Histogram图表和Dominator Tree。接着,针对卡顿问题,文章探讨了其产生原因,并提供了多种测试方法,包括GPU呈现模式分析、FPS Meter软件测试、绘制圆点计数法及Android Studio自带的GPU监控功能。最后,文章给出了排查卡顿问题的四个方向,帮助开发者优化应用性能。
169 4
Android性能测试——发现和定位内存泄露和卡顿
|
1月前
|
设计模式 Java Android开发
安卓应用开发中的内存泄漏检测与修复
【9月更文挑战第30天】在安卓应用开发过程中,内存泄漏是一个常见而又棘手的问题。它不仅会导致应用运行缓慢,还可能引发应用崩溃,严重影响用户体验。本文将深入探讨如何检测和修复内存泄漏,以提升应用性能和稳定性。我们将通过一个具体的代码示例,展示如何使用Android Studio的Memory Profiler工具来定位内存泄漏,并介绍几种常见的内存泄漏场景及其解决方案。无论你是初学者还是有经验的开发者,这篇文章都将为你提供实用的技巧和方法,帮助你打造更优质的安卓应用。
|
2月前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
70 0
|
3月前
|
编解码 Android开发 UED
【性能狂飙!】揭秘Android应用极速变身秘籍:内存瘦身+用户体验升级,打造丝滑流畅新境界!
【8月更文挑战第12天】构建高效Android应用需全方位优化,尤其重视内存管理和用户体验。通过弱引用降低内存占用,懒加载资源减少启动负担。运用Kotlin协程确保UI流畅不阻塞,响应式设计适配多屏需求。这些策略共同提升了应用性能与用户满意度。
56 1
|
3月前
|
缓存 监控 Android开发
构建高效的Android应用:从内存优化到用户体验
【7月更文挑战第57天】 在竞争激烈的移动市场中,一个高效、流畅且具有优秀用户体验的Android应用是成功的关键。本文将深入探讨如何通过内存管理和界面优化来提升应用性能,包括实用的编程技巧和策略,以及如何利用Android系统提供的工具进行调试和性能监控。读者将学习到如何识别和解决常见的性能瓶颈,以及如何设计出既美观又实用的用户界面。
|
4月前
|
消息中间件 Android开发 开发者
🔍深度剖析Android内存泄漏,让你的App远离崩溃边缘,稳如老狗!🐶
【7月更文挑战第28天】在 Android 开发中,内存管理至关重要。内存泄漏可悄无声息地累积,最终导致应用崩溃或性能下滑。它通常由不正确地持有 Activity 或 Fragment 的引用引起。常见原因包括静态变量持有组件引用、非静态内部类误用、Handler 使用不当、资源未关闭及集合对象未清理。使用 Android Studio Profiler 和 LeakCanary 可检测泄漏,修复方法涉及使用弱引用、改用静态内部类、妥善管理 Handler 和及时释放资源。良好的内存管理是保证应用稳定性的基石。
78 4