zoukankan      html  css  js  c++  java
  • Android

    内存泄漏:没有用的对象,无法被GC垃圾回收,就会造成内存泄漏(OOM)

    Handler如果使用不当,极大可能造成内存泄漏。比如:我们一般使用handler的方式,会在主线程中使用匿名类来创建handler:

    Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
            }
        };
    

    内存泄漏的原因:
    1. 在Java 中,非静态的内部类和匿名内部类都会隐式地持有其外部类的引用,静态的内部类不会持有外部类的引用。

    2. 而由于Handler原来,MessageQueue中的Message会对Handler持有引用,而handler会对Activity持有引用,即:
      message -----> handler ----->activity

    3. 所以,当Activity被销毁时,如果MessageQueue中仍然有message没有处理完,就会一直持有对Activity的引用,导致GC无法回收Activity,由此造成内存泄漏。

    两种解决方法:
    1. 将Handler定义为静态内部类,提高调用WeakReference来完成handler对Activity的弱引用。GC回收机制规定,当对象被其他对象弱引用时,允许GC对其回收。具体的代码实现:

    private static class MyHandler extends Handler{
        private WeakReference<MainActivity> weakReference;
        public MyHandler(MainActivity activity){
            weakReference = new WeakReference<>(activity);
        }
        Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            final Activity activity = weakReference.get();
            if (activity != null) {
                //实现相应逻辑
            }
         }
    }
    
    2 在Activity被销毁时,将未处理的message全部remove。代码实现:
    @Override
        protected void onDestroy() {
            super.onDestroy();
            handler.removeCallbacksAndMessages(null);
        }
    

    这样使用Handler,就不会造成内存泄漏了。
  • 相关阅读:
    dependencyManagement、parent与dependencies
    maven和gradle中,dependency和plugin的区别
    SpringMVC与Struts2区别
    RESTful风格与RESTful Api
    DBCP连接池配置参数
    js 函数的传值问题
    js 重载i
    js 对象与函数的区别
    子窗口 父窗口传值
    验证码
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/12844409.html
Copyright © 2011-2022 走看看