`
v5qqbrowser
  • 浏览: 357316 次
文章分类
社区版块
存档分类
最新评论

android开发中对context引用造成内存泄漏的一些猜测

 
阅读更多

Context在android特性空间被用来描述Activity的一组抽象行为,那么也就说有一个Activity就有一个Context(Activity是继承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 webview 内存泄露的解决方法

    Android webview 内存泄露的解决方法 最近在activity嵌套webview显示大量图文发现APP内存一直在涨,没法释放内存,查了很多资料,大概是webview的一个BUG,引用了activity导致内存泄漏,所以就尝试传递...

    避免 Android中Context引起的内存泄露

    本文主要介绍Android中Context引起的内存泄露的问题,这里对Context的知识做了详细讲解,说明如何避免内存泄漏的问题,有兴趣的小伙伴可以参考下

    谈谈Android里的Context的使用

    大家好,今天给大家分享一下Android里的Context的一些用法. 这里大致可以分为两种:一是传递Context参数,二是调用全局的Context. 其实我们应用启动的时候会启动Application这个类,这个类是在AndroidManifest.xml...

    5个Android开发中比较常见的内存泄漏问题及解决办法

    android中一个对象已经不需要了,但是其他对象还持有他的引用,导致他不能回收,导致这个对象暂存在内存中,这样内存泄漏就出现了。 内存泄漏出现多了,会是应用占用过多的没存,当占用的内存超过了系统分配的内存...

    android检查内存泄露

    android检查内存泄露和用法 &lt;!--==============================================================================--&gt; android:name="com.squareup.leakcanary.internal.HeapAnalyzerService" android:enabled...

    Android全局变量和Context

    Android全局变量和Context的实现方法

    Android Context使用例子.

    Android Context使用例子.

    深入解析Android App开发中Context的用法

    主要介绍了深入解析Android App开发中Context的用法,包括Context的创建场景和Context对资源的访问等内容,需要的朋友可以参考下

    开发工具 spring-context-4.3.6.RELEASE

    开发工具 spring-context-4.3.6.RELEASE开发工具 spring-context-4.3.6.RELEASE开发工具 spring-context-4.3.6.RELEASE开发工具 spring-context-4.3.6.RELEASE开发工具 spring-context-4.3.6.RELEASE开发工具 spring...

    android全局context工具类

    android:name="工具类的路径" 调用: Toast.makeText(MainApplication.getContext(), "文本", Toast.LENGTH_SHORT).show(); 不管你想在项目的任何地方使用Context,只需要调用一下MainApplication.getContext()...

    Android Context 浅析

    简要介绍android context 的用法

    android中用getApplicationContext()会不会避免某些内存泄漏问题?

    RT,在android开发中,如果在使用context的地方全部用getApplicationContext()会不会避免某些内存泄漏问题? 首先,Activity的Context和Application的Context肯定不是一个东西,一个是当前活动的 Context,它的生命...

    新版Android开发教程.rar

    � 采用了对有限内存、电池和 CPU 优化过的虚拟机 Dalvik , Android 的运行速度比想象的要快很多。 � 运营商(中国移动等)的大力支持,产业链条的热捧。 � 良好的盈利模式( 3/7 开),产业链条的各方:运营商、...

    Android的context使用

    家好,今天给大家分享一下Android里的Context的一些用法,以前经常有人在群里问我比如我在一个工具类里的某个方法,或者View里需要调用Context.但是工具类还有View里没有这个上下文怎么办?为了解决大家的疑问,我...

    Android编程获取全局Context的方法

    主要介绍了Android编程获取全局Context的方法,实例分析了基于Application类获取全局Context的实现步骤与相关技巧,需要的朋友可以参考下

    Android常见的几种内存泄漏小结

    在Android程序开发中,当一个对象已经不需要再使用了,本该被回收时,而另外一个正在使用的对象持有它的引用从而导致它不能被回收,这就导致本该被回收的对象不能被回收而停留在堆内存中,内存泄漏就产生了。内存...

Global site tag (gtag.js) - Google Analytics