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

简介: Handler内存泄漏原因及解决方案

一、Handler造成内存泄露的原因

在Activity中,将Handler声明成非静态内部类或匿名内部类,这样Handle默认持有外部类Activity的引用。如果Activity在销毁时,Handler还有未执行完或者正在执行的Message,而Handler又持有Activity的引用,导致GC无法回收Activity,导致内存泄漏。如以下两种情形可能导致内存泄漏

1、在Activity内将Handler声明成匿名内部类

   //匿名内部类
   private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };
   new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            //大量的操作,activity要销毁时还没结束
        }
    },1000);

2、在Activity内将Handler声明成非静态内部类:

   //非静态内部类
   private class MyHandler extends Handler{
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }
 
    private MyHandler mHandler = new MyHandler();

二、解决方案

1、静态内部类 + 弱引用

   private static class MyHandler extends Handler {
        //弱引用,在垃圾回收时,activity可被回收
        private WeakReference<MainActivity> mWeakReference;
 
        public MyHandler(MainActivity activity) {
            mWeakReference = new WeakReference<>(activity);
        }
 
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //清空handler管道和队列
        mHandler.removeCallbacksAndMessages(null);
    }

3:非静态内部类 + 弱引用,在activity要回收时清除引用(麻烦,不推荐)

    private class MyHandler extends Handler {
        //弱引用,在垃圾回收时,activity可被回收
        private WeakReference<MainActivity> mWeakReference;
 
        public MyHandler() {
            this.mWeakReference = new WeakReference<>(MainActivity.this);
        }
 
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    }
    
    private MyHandler mHandler = new MyHandler();
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //手动清除应用
        mHandler.mWeakReference.clear();
    }


目录
相关文章
|
9月前
|
运维 监控 Java
内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)
全网最全的内存溢出CPU占用过高排查文章,包含:问题出现现象+临时解决方案+复现问题+定位问题发生原因+优化代码+优化后进行压测,上线+复盘
1442 5
|
4天前
|
存储 缓存 监控
Linux系统内存下降:原因、诊断与解决方案
Linux系统内存下降:原因、诊断与解决方案
23 0
|
4天前
|
存储 监控 Java
JVM内存泄漏的分析与解决方案
JVM内存泄漏的分析与解决方案
|
6月前
|
Arthas Java 测试技术
微服务轮子项目(49) -常见JVM内存错误及解决方案
微服务轮子项目(49) -常见JVM内存错误及解决方案
70 0
|
6月前
|
存储 数据库 C语言
Hawkeyes: x86软件迁移Arm的弱内存序问题解决方案
本文介绍了x86软件迁移到Arm过程中可能遇到的弱内存序问题的解决方案,解析了弱内存序问题的根因,介绍了Hawkeyes的架构和实现原理。欢迎有需求的团队发送邮件咨询
660 0
|
9月前
|
存储 监控 NoSQL
深入探究Redis:内存模型、哨兵选举算法与脑裂解决方案
深入探究Redis:内存模型、哨兵选举算法与脑裂解决方案
418 1
|
10月前
|
前端开发 API PHP
php内存溢出:Allowed memory size of 1342bytes exhausted (tried to allocate 8192 bytes)本地配置和宝塔配置解决方案
php内存溢出:Allowed memory size of 1342bytes exhausted (tried to allocate 8192 bytes)本地配置和宝塔配置解决方案
92 0
|
10月前
|
算法 Java Android开发
JVM内存溢出及其解决方案
Java虚拟机(JVM)是执行Java程序的核心环境,它管理着应用程序的内存分配和回收。然而,在某些情况下,应用程序可能会遇到内存溢出的问题,即JVM无法为应用程序分配足够的内存空间。本文将探讨JVM内存溢出的原因以及解决方案,帮助开发人员更好地理解和处理这一问题。
215 0
|
消息中间件 存储 JavaScript
ThreadLocal 搭配线程池使用造成内存泄漏的原因和解决方案
ThreadLocal 搭配线程池使用造成内存泄漏的原因和解决方案
|
4天前
|
存储
浮点数在内存中的存储
浮点数在内存中的存储
25 0