android 单例模式内存泄露,单例模式导致的Android内存泄露

问题

项目开发中由于需要一个Util的单例化的存在,使用了单例模式,代码如下:

public class SingletonDemo {

private static volatile SingletonDemo instance;

private Context mContext;

private SingletonDemo(Context context) {

this.mContext = context;

}

public static SingletonDemo getInstance(Context context) {

if (instance == null) {

synchronized (SingletonDemo.class) {

if (instance == null) {

instance = new SingletonDemo(context);

}

}

}

return instance;

}

}

关于如何正确的创建单例模式可以参考这篇文章,在这个地方我们仅仅讨论传进context有没有问题?

详解

答案当然是有问题的,由于这个地方的context是个强引用,而且是被静态变量持有。在java中静态变量实在类被load的时候分配内存,在类被卸载的时候销毁。可以说static变量的生命周期伴随着进程的诞生和销毁。在Android系统中,当我们启动一个app的时候,系统启动一个进程加载一个Dalvik虚拟机实例,来负责类的加载和卸载以及GC,也就是说静态变量伴随了app进程的整个生命周期,由于上例中的instance持有了context,所以被传进来的activity(或者service或broadcast)自然没有办法得到释放,也就造成了内存泄露。

解决办法

其实这种需要单例的地方要仔细考虑好是否真的需要单例,因为在Android中静态变量其实是很不靠谱的,静态变量依附于进程,而Android在资源充足的时候是不会杀进程的,也就是说资源不足的情况下,进程随时可能被杀掉然后再具有资源的时候重启,那样存在静态变量里的值就很不靠谱了。如果说非得这么做不可,OK,使用context.getApplicationContext(),可以看一下Android developer上的解释:

There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.

Application在Android程序中是一种单例式的存在,它伴随了整个应用的始终,所以使用Application的context自然不会造成内存泄露了。

番外

在Android开发中组件之间传递参数尽量符合Android规范使用bundle来进行传递,不要使用static,因为static是依附于进程模型的,而Android中的组件如Activity,Service等是可以运行在不同的进程的。另外,由于进程的不安全,static中存储的值也自然不太可靠了。

http://techsummary.github.io/android/2015/05/11/singleton-memory-leak/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值