キャッシュ(cashcache)を作る
ふとしたひらめきから、java.lang.refパッケージを使わずにキャッシュを作ってみました。GCが発生すると、自動的に古いリンクを切ります。参照されたオブジェクトは自動的に末尾(最近参照した)に来るようにしてます。
自分でリンクを切るオブジェクトが選べるので、サイズや更新日時、メモリ容量などをみながらいろんな工夫が盛り込めそうです。
import java.util.*; public class AsanCache { /** キャッシュのキーと値を格納するマップ */ Map map = new HashMap(); /** 最近使ったキーを入れるキュー。末尾ほど新しい */ LinkedList queue = new LinkedList(); // 1.5ではjava.util.Queueが使える AsanCache() { new CacheRemover(); } public Object get(Object key) { Object result = map.get(key); if (queue.remove(key)) { // キューの中にキーがあれば末尾に移動させる queue.addLast(key); } return result; } public void put(Object key, Object value) { map.put(key, value); queue.addLast(key); } public void clear() { map.clear(); queue.clear(); } /** GC時に古いキャッシュを削除する */ class CacheRemover { public void finalize() { System.out.println("GC!"); // 古いキャッシュを削除する。ここでは最近の3件のみを残している。 while (queue.size() > 3) { Object key = queue.removeFirst(); map.remove(key); } // 次のGC時に動くようにリンク切れのオブジェクトを作る。 new CacheRemover(); } } public static void main(String[] args) { AsanCache cache = new AsanCache(); for (int i=0; i<100; i++) { cache.put(""+i, new byte[1000*1000]); } for (int i=0; i<100; i++) { System.out.println("key["+i+"]="+cache.get(""+i)); } } }
あー、GC中にnewするのはよくないでしょーね。
アイディアとしては面白いけど、使わない方がいいでしょう。