android开发中对context引用造成内存泄漏的一些猜测
2012-12-24 14:13
387 查看
Context在android特性空间被用来描述Activity的一组抽象行为,那么也就说有一个Activity就有一个Context(Activity是继承Context的)。
我们在开发应用程序的时候总是会遇到这样的问题:
从上面的代码我们可以看到MyManager是依赖于MyActivity,同时MyActivity也依赖于MyManager,两个类形成了双向依赖关系,也称为圈依赖。
这个时候有的同学担心,这个时候用context作为参数传递到MyManager中,当myactivity被回收之后,会不会导致内存泄漏。本人给出的答案是不会造成内存泄漏的
因为两个类处于圈依赖关系,并且属于双向可到达状态,但是两个类都处于不可达到区域,也就是说除了这两个类之外,再没有第三个类引用这两个类,那么这种情况在GC的时候这两个类是会被同时回收掉的。
那么再换一个写法,我把MyManager改一下
我把MyManager写成了单例模式,那么这个类的生命周期就伴随整个应用的生命周期了。如果在这个时候android GC了MyActivity,但是由于MyManager仍然引用了MyActiviy(Context),所以MyActivity仍然无法被系统回收,这样就造成内存溢出了,那么这样的问题如何解决呢?我建议使用弱引用,继续上代码:
这里我分析一下为什么用弱引用,如果你对弱引用还不是很了解,那么请看我的这篇文章 《谈谈java中的WeakReference
》。回头我们分析,如果这个时候系统析构了MyActivity对象,那么也就意味着context对象被置空了,那这个时候MyManager由于引用了context的弱引用,所以不会影响对MyActivity的回收,当然context为null对象,所以Mymanager中用到context来处理业务的时候需要做空判断了。
我们在开发应用程序的时候总是会遇到这样的问题:
public class MyActivity extends Activity{ private MyManager mMyManager = null; /* (non-Javadoc) * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //...layout 初始化 mMyManager = new MyManager(this); }
public class MyManager { private Context mContext = null; public MyManager(Context context) { mContext = context; } }
从上面的代码我们可以看到MyManager是依赖于MyActivity,同时MyActivity也依赖于MyManager,两个类形成了双向依赖关系,也称为圈依赖。
这个时候有的同学担心,这个时候用context作为参数传递到MyManager中,当myactivity被回收之后,会不会导致内存泄漏。本人给出的答案是不会造成内存泄漏的
因为两个类处于圈依赖关系,并且属于双向可到达状态,但是两个类都处于不可达到区域,也就是说除了这两个类之外,再没有第三个类引用这两个类,那么这种情况在GC的时候这两个类是会被同时回收掉的。
那么再换一个写法,我把MyManager改一下
public class MyManager { private Context mContext = null; private static MyManager mInstance = null; public static MyManager getInstance(Context context) { if (mInstance == null) { synchronized (MyManager.class) { if (mInstance == null) { mInstance = new MyManager(context); } } } return mInstance; } private MyManager(Context context){ mContext = context; } }
public class MyActivity extends Activity{ private MyManager mMyManager = null; /* (non-Javadoc) * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //...layout 初始化 mMyManager = MyManager.getInstance(this); } }
我把MyManager写成了单例模式,那么这个类的生命周期就伴随整个应用的生命周期了。如果在这个时候android GC了MyActivity,但是由于MyManager仍然引用了MyActiviy(Context),所以MyActivity仍然无法被系统回收,这样就造成内存溢出了,那么这样的问题如何解决呢?我建议使用弱引用,继续上代码:
public class MyManager { private WeakReference<Context> wr = null; private static MyManager mInstance = null; public static MyManager getInstance(Context context) { if (mInstance == null) { synchronized (MyManager.class) { if (mInstance == null) { mInstance = new MyManager(context); } } } return mInstance; } private MyManager(Context context){ wr = new WeakReference<Context>(context); } }
这里我分析一下为什么用弱引用,如果你对弱引用还不是很了解,那么请看我的这篇文章 《谈谈java中的WeakReference
》。回头我们分析,如果这个时候系统析构了MyActivity对象,那么也就意味着context对象被置空了,那这个时候MyManager由于引用了context的弱引用,所以不会影响对MyActivity的回收,当然context为null对象,所以Mymanager中用到context来处理业务的时候需要做空判断了。
相关文章推荐
- android开发中对context引用造成内存泄漏的一些猜测
- 避免android程序开发内存泄漏-context
- Android开发网上的一些重要知识点
- Android开发中一些被冷落但却很有用的类和方法
- Android 开发中一些常见问题的总结汇总
- Android蓝牙开发的一些经验
- MVC 因Nuget管理包升级一些引用的DLL组件造成的无法强制转换为 System.Web.WebPages.Razor.Configuration.HostSection
- iOS开发--Block容易造成循环引用
- android开发常用到的一些网络通信包(转)
- 用java开发Android的socket的一些异常处理
- 一些在android开发中经常用的的代码片段
- [转载] Android开发优化之——使用软引用和弱引用
- Android开发有用的一些网站,不断更新
- (转)Android开发中一些命名规范
- Android开发中一些常用的工具类汇总
- Android开发中比较耗时的一些操作小结
- android开发的一些经验(转载,自己看看)
- Android开发中要注意的一些问题
- 分享android开发过程中用到的一些开源框架
- 收集一些android开发有用的资料