Android Handler内存泄漏原因及解决方案

目录:

1.须知:

  1. 主线程Looper生命周期和Activity的生命周期一致。
  2. 非静态内部类,或者匿名内部类。默认持有外部类引用。

2.原因:

Handler造成内存泄露的原因。非静态内部类,或者匿名内部类。使得Handler默认持有外部类的引用。在Activity销毁时,由于Handler可能有未执行完/正在执行的Message。导致Handler持有Activity的引用。进而导致GC无法回收Activity。

3.可能造成内存泄漏

匿名内部类:

  //匿名内部类
  Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
    }
  };

非静态内部类:

  //非静态内部类
  protected class AppHandler extends Handler {

    @Override
    public void handleMessage(Message msg) {
      switch (msg.what) {
        // TODO: 2019/4/30
      }
    }
  }

4.解决方法:

Activity销毁时,清空Handler中,未执行或正在执行的Callback以及Message。

  // 清空消息队列,移除对外部类的引用
  @Override
  protected void onDestroy() {
    super.onDestroy();
    mHandler.removeCallbacksAndMessages(null);

  }

  //Handler源码中removeCallbacksAndMessages()注释含义
  /**
   * Remove any pending posts of callbacks and sent messages whose
   * <var>obj</var> is <var>token</var>. If <var>token</var> is null,
   * all callbacks and messages will be removed.
   */
  public final void removeCallbacksAndMessages(Object token) {
    mQueue.removeCallbacksAndMessages(this, token);
  }

静态内部类+弱引用

  private static class AppHandler extends Handler {
    //弱引用,在垃圾回收时,被回收
    WeakReference<Activity> activity;

    AppHandler(Activity activity){
      this.activity=new WeakReference<Activity>(activity);
    }

    public void handleMessage(Message message){
      switch (message.what){
        //todo
      }
    }
  }

5. 其他:

即使内存泄漏了。待handler中的消息处理完。下次GC时即可回收本次未回收的内存。

以上就是Android Handler内存泄漏原因及解决方案的详细内容,更多关于Android Handler内存泄漏的资料请关注我们其它相关文章!

(0)

相关推荐

  • 浅谈Android应用的内存优化及Handler的内存泄漏问题

    一.Android内存基础 物理内存与进程内存 物理内存即移动设备上的RAM,当启动一个Android程序时,会启动一个Dalvik VM进程,系统会给它分配固定的内存空间(16M,32M不定),这块内存空间会映射到RAM上某个区域.然后这个Android程序就会运行在这块空间上.Java里会将这块空间分成Stack栈内存和Heap堆内存.stack里存放对象的引用,heap里存放实际对象数据. 在程序运行中会创建对象,如果未合理管理内存,比如不及时回收无效空间就会造成内存泄露,严重的话可能导致

  • Android Handler内存泄漏详解及其解决方案

    关联篇:深入Android的消息机制源码详解-Handler,MessageQueue与Looper关系 关联篇:HandlerThread 使用及其源码完全解析 在android开发过程中,我们可能会遇到过令人奔溃的OOM异常,面对这样的异常我们是既熟悉又深恶痛绝的,因为造成OOM的原因有很多种情况,如加载图片过大,某已不再使用的类未被GC及时回收等等......本篇我们就来分析其中一种造成OOM的场景,它就是罪恶的内存泄漏.对于这样的称呼,我们并不陌生,甚至屡次与之"并肩作战",

  • Android Handler内存泄漏原因及解决方案

    目录: 1.须知: 主线程Looper生命周期和Activity的生命周期一致. 非静态内部类,或者匿名内部类.默认持有外部类引用. 2.原因: Handler造成内存泄露的原因.非静态内部类,或者匿名内部类.使得Handler默认持有外部类的引用.在Activity销毁时,由于Handler可能有未执行完/正在执行的Message.导致Handler持有Activity的引用.进而导致GC无法回收Activity. 3.可能造成内存泄漏 匿名内部类: //匿名内部类 Handler handl

  • Android内存溢出及内存泄漏原因进行

    内存溢出(Out Of Memory):Android系统中每一个应用程序可以向系统申请一定的内存,当申请的内存不够用的时候,就产生了内存溢出. 内存泄漏:当某个对象不再被使用,即不再有变量引用它时,该对象占用的内存就会被系统回收.当某个对象不再被使用,但是在其他对象中仍然有变量引用它时,该对象占用的内存就无法被系统回收,从而导致了内存泄漏. 当内存泄漏过多时,可用内存空间会减少,应用程序申请的内存不够用,就会导致内存溢出. 内存溢出原因: 1.内存泄漏过多. 2.内存中加载的数据量超过内存的可

  • Android内存溢出及内存泄漏原因进解析

    内存溢出(Out Of Memory):Android系统中每一个应用程序可以向系统申请一定的内存,当申请的内存不够用的时候,就产生了内存溢出. 内存泄漏:当某个对象不再被使用,即不再有变量引用它时,该对象占用的内存就会被系统回收.当某个对象不再被使用,但是在其他对象中仍然有变量引用它时,该对象占用的内存就无法被系统回收,从而导致了内存泄漏. 当内存泄漏过多时,可用内存空间会减少,应用程序申请的内存不够用,就会导致内存溢出. 内存溢出原因: 1.内存泄漏过多. 2.内存中加载的数据量超过内存的可

  • java OOM内存泄漏原因及解决方法

    前言 这篇文章主要介绍了java OOM内存泄漏原因及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.什么是OOM OOM,全称"Out Of Memory",翻译成中文就是"内存用完了",当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error 二.为什么会OOM.出现的原因是什么 为什么会没有内存了呢?原因不外乎有两点: ① 分配的少了:比如虚拟机本身可

  • GoLang内存泄漏原因排查详解

    目录 背景 临时性内存泄漏 通道理解 背景 Go 语言中有对应的Go 内存回收机制,在Go采用 并发三色标记清除  算法, 但是由于实际的过程中 发现会有一些内存泄漏的常见,内存泄漏 分为: 临时性 和 永久性内存泄漏. 初步排查过程中: 发现Linux使用top 发现内存随着时间会持续的增加没有稳定在一个合理值中. 在使用 pprof ,BBC 等 Go的内存泄漏工具进行排查 临时性内存泄漏 指的释放内存 不及时,对应的内存在更晚时候释放,这类问题主要是 string,slice 和底层的Bu

  • Golang内存泄漏场景以及解决方案详析

    目录 1.字符串截取 2.切片截取引起子切片内存泄漏 3.没有重置丢失的子切片元素中的指针 4.函数数组传参 5.goroutine 6.定时器 1)time.After 2)timer.ticker 总结 1.字符串截取 func main() { var str0 = "12345678901234567890" str1 := str0[:10] } 以上代码,会有10字节的内存泄漏,我们知道,str0和str1底层共享内存,只要str1一直活跃,str0 就不会被回收,10字节

  • ThreadLocal导致JVM内存泄漏原因探究

    目录 为什么要使用ThreadLocal 使用ThreadLocal 具体实现 引发内存泄漏的原因 为什么要使用ThreadLocal 在一整个业务逻辑流程中,为了在不同的地方或者不同的方法中使用同一个对象,但是又不想在方法形参中加这个对象,那么就可以使用ThreadLocal来保存 ThreadLocal最大的应用场景就是跨方法进行参数传递 ThreadLocal可以给每一个线程绑定一个变量的副本 使用ThreadLocal ThreadLocal常用的方法其实也就下面几个 // 返回当前线程

  • Android Native 内存泄漏系统化解决方案

    导读:C++内存泄漏问题的分析.定位一直是Android平台上困扰开发人员的难题.因为地图渲染.导航等核心功能对性能要求很高,高德地图APP中存在大量的C++代码.解决这个问题对于产品质量尤为重要和关键,高德地图技术团队在实践中形成了一套自己的解决方案. 分析和定位内存泄漏问题的核心在于分配函数的统计和栈回溯.如果只知道内存分配点不知道调用栈会使问题变得格外复杂,增加解决成本,因此两者缺一不可. Android中Bionic的malloc_debug模块对内存分配函数的监控及统计是比较完善的,但

  • Android中内存泄漏需要的注意点

    内存泄漏对每一位 Android 开发一定是司空见惯,大家或多或少都肯定有些许接触.大家都知道,每一个手机都有一定的承载上限,多处的内存泄漏堆积一定会堆积如山,最终出现内存爆炸 OOM. 而这,也是极有可能在 Android 面试中一道常见的开放题. 内存泄漏的根本原因是一个长生命周期的对象持有了一个短生命周期的对象.如果你对垃圾回收机制有所了解,我想这个问题基本难不住你,因为知道了原理,自然不会去触碰这些极易导致内存泄漏的雷区. 该题重在积累,不需要死记硬背,自己多总结即可. 1. 长生命周期

随机推荐