美文网首页
Android内存泄漏(二):匿名类

Android内存泄漏(二):匿名类

作者: meixinxicun | 来源:发表于2017-03-22 12:31 被阅读1032次

上一节已经介绍了内存泄漏与引用的关系,那么这一节强化一下,看看匿名类跟内存泄漏和引用又存在着什么样的关系呢。

匿名类定义

在实际的项目中看到一个很奇怪的现象,Java可以直接new一个接口,然后在new里面粗暴的加入实现代码,向下面这样:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println(this.getClass());
    }
};
runnable.run();

匿名类相当于在定义类的同时再新建这个类的实例

知识点

匿名类也持有着外部类的强引用。

案例1_匿名AsyncTsk

当你在Activity中定义了匿名的AsyncTsk,当异步任务在后台执行耗时任务期间,Activity不幸被销毁了(用户退出,系统回收),这个被AsyncTask持有的Activity实例就不会被垃圾回收器回收,直到异步任务结束。
我们来看如下代码:

//创建匿名类
void startAsyncTask() {
    new AsyncTask<Void, Void, Void>() {
        @Override protected Void doInBackground(Void... params) {
            while(true);
        }
    }.execute();
}
//匿名类使用
button.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        startAsyncTask();
    }
});

如上代码中匿名类AsyncTask执行期间,所有持有的引用Activity被销毁,那么这个activity实例就无法被垃圾回收器回收,直到异步任务结束。

案例2_匿名Handler

同样道理,定义匿名的Runnable,用匿名类Handler执行。Runnable内部类会持有外部类的隐式强引用,被传递到Handler的消息队列MessageQueue中,在Message消息没有被处理之前,Activity实例不会被销毁了,于是导致内存泄漏。

//创建匿名类
void createHandler() {
    new Handler() {
        @Override public void handleMessage(Message message) {
            super.handleMessage(message);
        }
    }.postDelayed(new Runnable() {
        @Override public void run() {
            while(true);
        }
    }, Long.MAX_VALUE >> 1);
}

//匿名类使用
button.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        createHandler();
    }
});

案例3_匿名Thread

定义匿名的Thread未结束之前,Activity实例不会被销毁,也会导致内存泄漏。

//创建匿名类
void spawnThread() {
    new Thread() {
        @Override public void run() {
            while(true);
        }
    }.start();
}

//匿名类使用
button.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        spawnThread();
    }
});

案例4_匿名TimerTask

定义匿名的TimerTask未结束之前,Activity实例不会被销毁,也会导致内存泄漏。

//创建匿名类
void scheduleTimer() {
    new Timer().schedule(new TimerTask() {
        @Override
        public void run() {
            while(true);
        }
    }, Long.MAX_VALUE >> 1);
}

//匿名类使用
button.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
        scheduleTimer();
    }
});

总结

看了上面4个例子,我们来总结一下:只要是匿名类的实例,不管是不是在工作线程中,都会持有外部类(Activity)的强引用,导致内存泄漏。

上一节:Android内存泄漏(一):引用
下一节:Android内存泄漏(三):单例

相关文章

  • Android内存泄漏(二):匿名类

    上一节已经介绍了内存泄漏与引用的关系,那么这一节强化一下,看看匿名类跟内存泄漏和引用又存在着什么样的关系呢。 匿名...

  • Android内存泄漏之集合类

    Android内存泄漏基本可以分为以下四大类:1、集合类泄漏2、单例/静态变量造成的内存泄漏3、匿名内部类/非静态...

  • Android性能-内存泄漏

    泄漏原因: 单例造成的内存泄漏 非静态内部类(匿名类等)创建静态实例造成的内存泄漏 Handler/Thread/...

  • Android 优化

    Android 内存优化内存溢出 , 内存泄漏 , 内存泄漏过多就导致内存溢出 Android 系统垃圾回收机制内...

  • (转载自diycode)2017 Android 面试题分享整理

    Android(安卓) Android基础知识 Android内存泄漏总结 Handler内存泄漏分析及解决 An...

  • Android 基础

    1、Android布局 2、Android内存泄漏总结 3 、Handler内存泄漏分析及解决 4...

  • android内存泄露

    参考内存泄露从入门到精通三部曲之基础知识篇Android 内存泄漏总结Android内存泄漏研究Android内存...

  • Android常见内存泄漏

    内存泄漏场景: 静态变量引用非静态内部类/匿名类实例。子线程相关的非静态内部类/匿名内部类引用。Handler导致...

  • Android内存泄漏场景及解决方法

    本文包括以下内容: 内存泄漏原理 Android内存泄漏发生的情况 检测内存泄漏的工具、方法 如何避免内存泄漏 更...

  • Android性能优化

    1.Android性能优化-内存泄漏(上) 2.Android性能优化-内存泄漏(下) 3.Android性能优化...

网友评论

      本文标题:Android内存泄漏(二):匿名类

      本文链接:https://www.haomeiwen.com/subject/jvqonttx.html