JavaのWeakReferenceの動作を確認する。
import java.lang.ref.WeakReference; import java.util.WeakHashMap; public class Main { static class Entry{ private final String name; public Entry(String name) { this.name = name; } @Override public String toString() { return name; } } public static void main(String[] args) { var val = new Entry("Hello"); var ref = new WeakReference<>(val); System.out.println("ref: "+ val + ", weak-ref: "+ ref.get()); System.out.println("gc"); System.gc(); System.out.println("ref: "+ val + ", weak-ref: "+ ref.get()); System.out.println("e = null"); val = null; System.out.println("gc"); System.gc(); System.out.println("ref: "+ val + ", weak-ref: "+ ref.get()); } }
実行結果は以下。
ref: Hello, weak-ref: Hello gc ref: Hello, weak-ref: Hello e = null gc ref: null, weak-ref: null
ちなみに, var e = "Hello"; でも同じ結果を期待したのだけれど,GCされずに残った。
ref: Hello, weak-ref: Hello gc ref: Hello, weak-ref: Hello e = null gc ref: null, weak-ref: Hello
多分,"Hello"はグローバル変数として保持されるため,GC対象にならない。そこで以下のように明示的にnewすると同じ結果になった。
var e = new String("Hello");
StringでなくIntegerとかで試すときもvalueOfは勝手にキャッシュされるので注意は必要。