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

目录
相关文章
|
18天前
|
存储 监控 算法
LeakCanary 的内存泄露问题排查
LeakCanary 的内存泄露问题排查
24 0
|
2月前
|
存储 开发工具 Android开发
构建高效的Android应用:从内存管理到用户界面
【5月更文挑战第29天】 随着智能手机的普及,Android应用的开发变得日益重要。然而,许多开发者在开发过程中忽视了性能优化,导致应用运行缓慢,用户体验差。本文将深入探讨如何通过有效的内存管理和用户界面优化,提升Android应用的性能。我们将详细介绍内存泄漏的原因和解决方案,以及如何使用Android的新特性来创建流畅的用户界面。无论你是新手还是经验丰富的开发者,都可以从本文中获得有用的技巧和建议。
|
5天前
|
存储 缓存 Java
Android性能优化:内存管理与LeakCanary技术详解
【7月更文挑战第21天】内存管理是Android性能优化的关键部分,而LeakCanary则是进行内存泄漏检测和修复的强大工具。
|
1月前
|
机器学习/深度学习 分布式计算 JavaScript
心得经验总结:折腾几天,内存检测工具写出来了
心得经验总结:次奥,折腾几天,内存检测工具写出来了
14 0
|
1月前
|
缓存 Linux
centos内存检测工具
【6月更文挑战第1天】centos内存检测工具
72 3
|
1月前
|
监控 Linux 测试技术
edac是检测什么的,和centos内存条损害检测工具
【6月更文挑战第1天】edac是检测什么的,和centos内存条损害检测工具
46 2
|
2月前
|
移动开发 监控 Android开发
构建高效Android应用:从内存优化到电池寿命代码之美:从功能实现到艺术创作
【5月更文挑战第28天】 在移动开发领域,特别是针对Android系统,性能优化始终是关键议题之一。本文深入探讨了如何通过细致的内存管理和电池使用策略,提升Android应用的运行效率和用户体验。文章不仅涵盖了现代Android设备上常见的内存泄漏问题,还提出了有效的解决方案,包括代码级优化和使用工具进行诊断。同时,文中也详细阐述了如何通过减少不必要的后台服务、合理管理设备唤醒锁以及优化网络调用等手段延长应用的电池续航时间。这些方法和技术旨在帮助开发者构建更加健壮、高效的Android应用程序。
|
1月前
|
大数据 API Android开发
Android MemoryFile 共享内存
Android MemoryFile 共享内存
22 0
|
1月前
|
缓存 Java Linux
Android 匿名内存深入分析
Android 匿名内存深入分析
19 0
|
2月前
|
监控 Android开发 UED
构建高效的Android应用:从内存管理到用户体验
【5月更文挑战第28天】 在移动开发的世界中,打造一个既快速又高效的Android应用是每个开发者追求的目标。本文将深入探讨如何通过合理的内存管理策略、优化的代码实践和用户界面设计的提升来增强应用性能。我们将剖析内存泄漏的根源,提供解决方案,探索Kotlin与Java在性能上的差异,并分析如何利用Android系统提供的工具监控和改善应用表现。此外,我们还将讨论Material Design的应用以及其对用户体验的影响。通过这些技术的综合运用,你将能够为用户提供更流畅、响应更快的使用体验。