android------強引用、ソフト引用、弱引用、虚引用使用

4596 ワード

Javaでは、プログラマが手動でオブジェクトのライフサイクルを管理する必要はありませんが、メモリが不足している場合、JVMがOutOfMemoryのエラーを回避するためにオブジェクトを自動的に回収するなど、一定のライフサイクルを持つオブジェクトを望む場合は、ソフトリファレンスと弱いリファレンスを使用する必要があります.
Java SE 2からは、強参照、ソフト参照、弱参照、虚参照の4種類の参照が提供されています.Javaでこの4つの参照タイプを提供するには、主に2つの目的があります.1つ目は、プログラマがコードによって特定のオブジェクトのライフサイクルを決定できることです.第二に、JVMのゴミ回収に有利である.以下に、この4つのタイプの参照の概念を説明します.
 
参照は4つに分けられ、高いレベルから低いレベルまでこれを強い参照-ソフト参照-弱い参照-虚参照とする.
  • 参照タイプ
    カテゴリ
    リサイクルメカニズム
    用途
    生存時間
    強参照
    未回収
    オブジェクトのステータス
    JVM停止時
    ソフトリファレンス
    メモリ不足時の回収
    キャッシュ
    メモリ不足
    弱い参照
    オブジェクトが参照されない場合に回収
    キャッシュ
    GC運転後
    ダミーリファレンス
    対象が回収された場合
    正確なメモリ安定性の管理
    unknown

  •  
    強いリファレンス(Strong Reference)は回収されません.強いリファレンスはプログラムコードの中に普遍的に存在し、Object obj = new Object()のようなリファレンスは、強いリファレンスがまだ存在する限り、ゴミ収集器は参照されたオブジェクトを回収しません.
     
    弱いリファレンス(Soft Reference)はオブジェクトを重点的に回収します.弱いリファレンスも非必須オブジェクトを記述するために使用され、弱いリファレンスに関連付けられたオブジェクトは次のゴミ収集が発生する前にしか生存できません.
     
    ソフトリファレンス(Weak Reference)メモリがオーバーフローしようとしているときに回収されます.ソフトリファレンスは、まだ役に立つが必要ではないオブジェクトを記述するために使用されます.ソフトリファレンスに関連付けられているオブジェクトについては、システムにメモリオーバーフロー異常が発生する前に、これらのオブジェクトリストの回収範囲の中から二次回収が行われます.今回の回収で十分なメモリがない場合、メモリオーバーフロー異常が放出されます.
     
    ダミーリファレンス(了解)(Phantom Reference)ダミーリファレンスは幽霊リファレンスまたは幻影リファレンスとも呼ばれ、最も弱いリファレンス関係である.1つのオブジェクトにダミーリファレンスが存在するかどうかは、その生存時間に全く影響を及ぼさず、ダミーリファレンスによってオブジェクトインスタンスを取得することもできない.1つのオブジェクトにダミーリファレンス関連を設定する唯一の目的は、このオブジェクトがコレクタによって回収されるときにシステム通知を受信しました.
     
    よく使用される弱い参照とソフト参照
    たとえば、ピクチャロードフレームワークでは、メモリキャッシュを弱引用で実現します.
    //          
    public class AsyncImageLoader
    {
        // Url  ,SoftReference  ,    HashMap   。
        private Map> mImageCache =
            new HashMap>();
         
        //        
        public Drawable loadDrawable(final String imageUrl, final ImageCallback callback)
        {
            //    ,                 
            if(mImageCache.containsKey(imageUrl))
            {
                SoftReference softReference = mImageCache.get(imageUrl);
                if (softReference.get() != null)
                {
                    return softReference.get();
                }
            }
             
            final Handler handler = new Handler()
            {
                @Override
                public void dispatchMessage(Message msg)
                {
                    //  ImageCallbackImpl  imageLoad  ,   (UI  )   。
                    callback.imageLoad((Drawable)msg.obj);
                }
            };
             
            /*      ,       ,            ,
             *        Drawable   Handler   ,       UI          
             */
            new Thread()
            {      
                public void run()
                {
                    Drawable drawable = loadImageFromUrl(imageUrl);
                    //            
                    mImageCache.put(imageUrl, new SoftReference(drawable));
                    Message message = handler.obtainMessage(0, drawable);
                    handler.sendMessage(message);
                };
            }.start();
             
            //       ,           ,    null;
            return null;
             
        }
         
        //        
        public interface ImageCallback
        {
            void imageLoad(Drawable drawable);
        }
         
        //  Url       Drawable  ;
        protected Drawable loadImageFromUrl(String imageUrl)
        {
            try {
                return Drawable.createFromStream(new URL(imageUrl).openStream(),"debug");
            } catch (Exception e) {
                // TODO: handle exception
                throw new RuntimeException(e);
            }
        }
    }

    Handler弱リファレンス、メモリ漏れ防止
    public class MainActivity extends AppCompatActivity {
     
        private Handler handler  ;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
     
            handler = new MyHandler( this ) ;
     
            new Thread(new Runnable() {
                @Override
                public void run() {
                   handler.sendEmptyMessage( 0 ) ;
                }
            }).start() ;
     
        }
     
        private static class MyHandler extends Handler {
            WeakReference weakReference ;
     
            public MyHandler(MainActivity activity ){
                weakReference  = new WeakReference( activity) ;
            }
     
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if ( weakReference.get() != null ){
                    // update android ui
                }
            }
        }
     
    }