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();
    }


目录
相关文章
|
7月前
|
监控 Java 计算机视觉
Python图像处理中的内存泄漏问题:原因、检测与解决方案
在Python图像处理中,内存泄漏是常见问题,尤其在处理大图像时。本文探讨了内存泄漏的原因(如大图像数据、循环引用、外部库使用等),并介绍了检测工具(如memory_profiler、objgraph、tracemalloc)和解决方法(如显式释放资源、避免循环引用、选择良好内存管理的库)。通过具体代码示例,帮助开发者有效应对内存泄漏挑战。
319 1
|
9月前
|
运维 监控 Java
为何内存不够用?微服务改造启动多个Spring Boot的陷阱与解决方案
本文记录并复盘了生产环境中Spring Boot应用内存占用过高的问题及解决过程。系统上线初期运行正常,但随着业务量上升,多个Spring Boot应用共占用了64G内存中的大部分,导致应用假死。通过jps和jmap工具排查发现,原因是运维人员未设置JVM参数,导致默认配置下每个应用占用近12G内存。最终通过调整JVM参数、优化堆内存大小等措施解决了问题。建议在生产环境中合理设置JVM参数,避免资源浪费和性能问题。
540 3
|
10月前
|
存储 架构师 Java
内存溢出原因与解决方案(4大主流方案详解)
本文详解内存溢出(OOM)的原因及解决方案。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
内存溢出原因与解决方案(4大主流方案详解)
|
Web App开发 缓存 JavaScript
技术分享:深入探索内存泄漏——识别、分类与解决方案
【8月更文挑战第27天】在软件开发的浩瀚星海中,内存管理始终是程序员们必须面对的重要课题。内存泄漏,作为内存管理不善的典型症状,不仅影响应用性能,还可能导致系统崩溃,是每位开发者都需警惕的“暗礁”。本文将带您深入探索内存泄漏的本质、常见类型及有效的解决策略,助力您的工作学习之旅更加顺畅。
133 0
|
存储 缓存 NoSQL
Redis是一种高性能的内存数据库,常用于高并发环境下的缓存解决方案
【6月更文挑战第18天】**Redis摘要:** 高性能内存数据库,擅长高并发缓存。数据存内存,访问迅速;支持字符串、列表等多元数据类型;具备持久化防止数据丢失;丰富命令集便于操作;通过节点集群实现数据分片与负载均衡,增强可用性和扩展性。理想的缓存解决方案。
191 1
|
设计模式 安全 Java
Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
248 0
|
监控
LabVIEW程序内存泄漏分析与解决方案
LabVIEW程序内存泄漏分析与解决方案
468 0
|
存储 监控 Java
JVM内存泄漏的分析与解决方案
JVM内存泄漏的分析与解决方案
228 2
|
存储 缓存 监控
Linux系统内存下降:原因、诊断与解决方案
Linux系统内存下降:原因、诊断与解决方案
334 0
|
2月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
550 0

热门文章

最新文章