広告

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」をご参照ください。


関連記事

ページの先頭へ