Android 中的内存泄漏

JVM垃圾回收机制 会对没有引用的对象进行回收,而持有引用的对象是不能被回收的。

匿名内部类包含如下特征
1. new 操作符
2. 实现一个接口,或者继承自一个类
3. 有构造函数的调用,接口因为没有构造函数,默认是无参构造函数。
4. 拥有body,就像类定义一样,body内可以声明方法,但是 不能拓展构造函数。

匿名内部内可以直接访问本地类的成员变量。可访问 方法内通过final 修饰的本地变量。
因此常见的泄漏就是匿名内部类存在对act的引用。

  private Object obj=new Object(){
        @Override
        public String toString() {
            return super.toString()+"bbb";
        }
    };

然后把obj 赋值给某静态变量,此时 内存泄漏又出来了。 因此匿名内部类会持有所在类的引用

XXXActivity@1 这样子的就是匿名内部类。

Java 和 Kotlin中的Handler 造成的泄漏出现不一样的结果,

我在java中是这么写的:

 new Handler().postDelayed(new Runnable() {
            @Override public void run() {
                Log.d("TAG","testtest");
            }
        }, 60000);

Kotlin 中用lambda表达式。

Handler().postDelayed({ Log.d("TAG", "testtest") }, 60000)

实测 java版本的代码会造成内存泄漏,而kotlin版本就不会,为什么会出现这种情况?
messageQueue中有引用Runnable,而runnable 持有Act 的引用,所以会有内存泄漏,而kotlin 在编译的时候并没有在代码中生成一个匿名内部类,只是一个runnable。没有存在对act的引用,但是,如果在代码中用到了activity的成员变量,也会造成引用,(为什么? )

Leave a Reply

Your email address will not be published. Required fields are marked *