Android 进阶解密阅读笔记22

内存优化

相比绘制优化,内存优化的价值我觉得相对更高些。内存泄漏又是内存优化中比较重点的一块,并且也是日常开发中最容易接触到的。

内存泄漏

造成内存泄漏的情况说白了就是该销毁的对象(没有用了)没有被 GC 回收掉,这就造成了这些对象就像是孤魂野鬼一样,越积越多的话还会造成 OOM 问题。

常见的几种造成内存泄漏的场景有,

  1. 非静态内部类或匿名内部类引起
    首先明确一点就是非静态内部类或者匿名内部类会隐式持有外部类的对象引用,而由此就会存在引发内存泄漏的可能。
    a 非静态内部类的静态实例。就是说在外部类声明了一个非静态内部类的对象实例,并且是用 static 修饰的,由此就会导致静态实例一直会持有外部类对象引用,那么外部类想被回收也回收不掉。
    b 非静态内部类或匿名内部类的耗时任务。例如在 Activity 这种组件上,耗时任务一般会另开线程执行,当 Activity 退出销毁时,由于非静态内部类或匿名内部类的任务还没做完,导致还持有着 Activity 对象引用,这样一来 Activity 就没办法被回收了。
    c Handler 内存泄漏。一般在用的时候会用 new Handler() 来实现一个非静态内部类,而由于 Handler 是 Android 系统消息循环机制里的一环,从而会存在一个情况就是,发送一个延时消息,之后 Activity 又退出销毁了,而此时消息还没有被执行,存在消息循环队列里,这就会持有 Handler 对象,而这个 Handler 对象又持有外部类 Activity 对象引用,使得 Activity 就不能被回收。
    这类的解决方案关键还是要避免外部类想要销毁时被非静态内部类所持有,一种是在外部类准备销毁时,解除引用关系,例如在 Activity 的 onDestroy() 方法里将那个延时消息从队列中移除;另一种是将非静态内部类转为静态内部类,这样虽说是内部类,但两个类其实就没什么关联了。

  2. 未正确使用 Context
    要注意区分 Application 和 Activity 的 Context 的生命周期。我问你答-简述 Application 和 Activity 的 Context

  3. WebView

  4. 资源对象未关闭
    对于文件读写,数据库操作等场景,要注意用完相关资源(File, Cursor 等)后及时做关闭释放资源。

  5. Bitmap 对象

  6. 监听器未关闭

内存使用分析工具

  • Memory Monitor

    这个其实应该在目前较新版本的 Android Studio 里找不到了,换了一个更新的工具叫 Profiler
    Android Studio Profiler.jpg
    就像截图里的这样,用 usb 方式连接上电脑后就可以实时观察应用的 CPU, 内存,网络,电量的使用情况,并且点击每个都还可以更细致的监测。
  • Allocation Tracker

  • Heap Dump

  • MAT

LeakCanary

上来就整个链接,因为这个对于我们 Android 分析查找内存泄漏的问题真的太方便,太好用了。LeakCanary Android/Java 内存泄露检测框架。你可以理解为可以用它来替换 MAT 来分析在 Android 方面的内存泄漏问题。

你可能感兴趣的:(Android 进阶解密阅读笔记22)