zoukankan      html  css  js  c++  java
  • android内存泄露--案例一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);
        }
    }
  • 相关阅读:
    NGINX原理分析 之 SLAB分配机制
    graphviz
    使用git Rebase让历史变得清晰
    An Implementation of Double-Array Trie
    转录组差异表达分析小实战(一)
    简单使用limma做差异分析
    简单使用DESeq2/EdgeR做差异分析
    简单使用DESeq做差异分析
    HISAT,sTRINGTIE,ballgown三款RNA-seq信息分析软件
    转录组的组装Stingtie和Cufflinks
  • 原文地址:https://www.cnblogs.com/zhengtu2015/p/4901007.html
Copyright © 2011-2022 走看看