Page List

Search on the blog

2013年9月7日土曜日

WeakReferenceとWeakHashMap

 Javaのweak reference(弱参照)について勉強してみた。

weak referenceとは?
Javaには、以下の4種類の参照がある。
  • Strong Reference
  • Weak Reference
  • Soft Reference
  • Phantom Reference
Strong Referenceはいわゆる普通の参照。あるオブジェクトに対するStrong Referenceが無くならない限り、そのオブジェクトはGCの対象になりません。

これに対して、Weak Referenceの場合は、オブジェクトをメモリ上に留めておく効果のない弱い参照です。あるオブジェクトへの参照がWeak Referenceだけの場合そのオブジェクトはGCの対象になります。

Soft Reference、Phantom Referenceについては参考資料[1]参照。

何に使うの?
Mapを使ってキャッシュを実現したいときや、同じくMapを使ってオブジェクトにシリアルな番号を振って管理したい場合などに使われるらしいです[1]。
あとはこれが分かりやすい。transientなオブジェクトのmetadataをMapで管理するとき[2]。

サンプル
まずWeak Referenceを試してみます。
package com.kenjih.test;

import java.lang.ref.WeakReference;

public class Clazz {

    public void run() throws Exception {
        SomeClass someObject = new SomeClass();
        WeakReference<SomeClass> weakSomeObject = new WeakReference<SomeClass>(
                someObject);
        System.out.println(weakSomeObject.get());
        someObject = new SomeClass();
        System.gc();
        System.out.println(weakSomeObject.get());
    }

    public static void main(String[] args) throws Exception {
        new Clazz().run();
    }
}

実行結果は以下のようになります。
$ com.kenjih.test.SomeClass@d16610
$ null

someObjectがStrong Reference、weakSomeObjectがWeak Referenceです。イメージとしては以下のような感じかなと思っています。System.gc()を呼び出したときにWeak Referenceからのみ参照されているオブジェクトはGCされます。


















 つぎにWeakHashMapのサンプル。WeakHashMapは、weak keyを利用したHashMap。keyに対するStrong Referenceが無くなったら、GCでそのkeyに対するマッピングがmapから削除される。
package com.kenjih.test;

import java.util.Map;
import java.util.WeakHashMap;

public class Clazz {

    public void run() throws Exception {
        Map<SomeClass, AnotherClass> map = new WeakHashMap<SomeClass, AnotherClass>();
        
        SomeClass someObject = new SomeClass();
        map.put(someObject, new AnotherClass());
        someObject = new SomeClass();
        System.gc();
        System.out.println(map);        
    }

    public static void main(String[] args) throws Exception {
        new Clazz().run();
    }
}

実行結果は以下のとおり。
$ {}

参考資料
[1] Understanding Weak References
[2] Java theory and practice: Plugging memory leaks with weak references

0 件のコメント:

コメントを投稿