Java : SoftReference (ソフト参照) - API使用例
SoftReference (Java SE 18 & JDK 18) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。
概要
SoftReferenceクラスは、対象となるオブジェクトのソフト参照を作ります。
ソフト参照では、対象オブジェクトの強参照がすべてなくなっても、GC でクリアされないことがあります。
ガベージ・コレクタが、
- 現在のメモリ状況
- ソフト参照の使用頻度(最近使ったものほどクリアされにくい)
などを判断して、クリアする/しないが決定されます。
オブジェクトがクリアされると、ソフト参照は null を返します。
var sb = new StringBuilder("abcd");
final var ref = new SoftReference<>(sb);
// 変数 sb による強参照が残っている状態です。
System.gc();
System.out.println(ref.get()); // abcd
// 変数 sb による強参照をクリアします。
sb = null;
// 強参照がなくなっても、GCでクリアされるとは限りません。
System.gc();
System.out.println(ref.get()); // abcd
// ↑今回の例では、クリアされませんでした。
try {
// 意図的に OutOfMemoryError を発生させます。
final var bytes = new byte[1000000000];
} catch (OutOfMemoryError e) {
System.out.println(e.getMessage()); // Java heap space
}
// OutOfMemoryError が発生すると、ソフト参照がクリアされていることが保証されます。
System.out.println(ref.get()); // null
補足
- 本記事のコード例では、GCを実行するために System.gc メソッドを使っています。
- しかし、一般的なJavaプログラムでは、System.gc を直接呼び出すことはあまりおすすめしません。
Javaシステムが自分自身の最適なタイミングでGCを実行してくれるためです。
コンストラクタ
SoftReference (T referent)
var sb = new StringBuilder("abcd");
final var ref = new SoftReference<>(sb);
System.out.println(ref.get()); // abcd
sb = null;
System.gc();
System.out.println(ref.get()); // abcd
try {
// 意図的に OutOfMemoryError を発生させます。
final var bytes = new byte[1000000000];
} catch (OutOfMemoryError e) {
System.out.println(e.getMessage()); // Java heap space
}
System.out.println(ref.get()); // null
SoftReference (T referent, ReferenceQueue<? super T> q)
final var queue = new ReferenceQueue<StringBuilder>();
var sb = new StringBuilder("abcd");
final var ref = new SoftReference<>(sb, queue);
System.out.println(ref.get()); // abcd
System.out.println(queue.poll()); // null
sb = null;
System.gc();
System.out.println(ref.get()); // abcd
System.out.println(queue.poll()); // null
try {
// 意図的に OutOfMemoryError を発生させます。
final var bytes = new byte[1000000000];
} catch (OutOfMemoryError e) {
System.out.println(e.getMessage()); // Java heap space
}
System.out.println(ref.get()); // null
System.out.println(queue.poll()); // java.lang.ref.SoftReference@63bfd328
メソッド
T get ()
get の使用例は、SoftReference(T referent) にまとめて記載しました。
そちらのAPI使用例をご参照ください。
Referenceで宣言されたメソッド
clear, clone, enqueue, isEnqueued, reachabilityFence, refersTo
「Java API 使用例 : Reference」をご参照ください。