static关键字所导致的内存泄漏问题

大家都知道内存泄漏和内存溢出是不一样的,内存泄漏所导致的越来越多的内存得不到回收的失手,最终就有可能导致内存溢出,下面说一下使用staitc属性所导致的内存泄漏的问题。

在dalvik虚拟机中,static变量所指向的内存引用,如果不把它设置为null,GC是永远不会回收这个对象的,所以就有了以下情况:

public class SecondActivity extends Activity{
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            SecondActivity.this.finish();
            this.removeMessages(0);
        }
    };

    private static Haha haha;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        haha = new Haha();
        mHandler.sendEmptyMessageDelayed(0,2000);
    }

    class Haha{

    }
}
非静态内部类的静态引用。然后在2秒之后我们要finish掉这个activity,会造成什么问题呢?我们知道,内部类和外部类之间是相互持有引用的,SecondActivity实例持有了haha的引用,但这里haha是用static修饰的,上面说了,虚拟机不会回收haha这个对象,从而导致SecondActivity实例也得不到回收,造成内存溢出。


这货还在这得不到回收。

怎么解决这个问题呢,很简单,只要在Activity的onDestroy方法里把haha设为null就行啦

    protected void onDestroy() {
        super.onDestroy();
        if(haha!=null){
            haha = null;
        }
    }


那么还有另外一种情况,单例的问题。单例也是用了其static属性,很多单例,往往需要用到context对象,而又是通过传值的方式获得,比如:

先来一个单例

public class SingleInstanceF {
    private static SingleInstanceF single;
    private  Context context;

    private SingleInstanceF(Context context){
        this.context = context;
    }

    public static SingleInstanceF getInstance(Context context){
        if(single==null){
            single = new SingleInstanceF(context);
        }
        return single;
    }

}
再来一个Activity来用它,context传入一个this,再2秒之后关闭Activity

public class ThirdActivity extends Activity{
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            ThirdActivity.this.finish();
            this.removeMessages(0);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SingleInstanceF instanceF = SingleInstanceF.getInstance(this);
        mHandler.sendEmptyMessageDelayed(0,2000);
    }
}


后来我们发现这货还在,又是得不到回收:

怎么办呢,还是像上面那样,把静态对象设置为null,或者我们传入context的时候,别传this了,this可是当前Acitvity啊,传Application Context即可。但是不是都可以传Application Context呢,明显不是,有的事是Application Context干不了的,这个得看具体情况而定。









  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值