Java : PhantomReference with Examples

PhantomReference (Java SE 18 & JDK 18) API Examples.
You will find code examples on most PhantomReference methods.


Summary

Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed. Phantom references are most often used to schedule post-mortem cleanup actions.

Class diagram

class Foo {
    @SuppressWarnings("removal")
    @Override
    protected void finalize() {
        System.out.println("Finalize!");
    }
}

class FooRef extends PhantomReference<Foo> {
    FooRef(Foo referent, ReferenceQueue<? super Foo> q) {
        super(referent, q);
    }

    void clean() {
        System.out.println("Clean!");
    }
}

final var queue = new ReferenceQueue<Foo>();
final var executorService = Executors.newSingleThreadExecutor();

try {
    executorService.submit(() -> {
        try {
            var foo = new Foo();
            final var ref = new FooRef(foo, queue);

            // The get method of a phantom reference always returns null. 
            System.out.println("ref.get : " + ref.get());
            System.out.println("ref.referesTo : " + ref.refersTo(foo));

            System.out.println("queue.poll : " + queue.poll());

            foo = null;

            System.out.println("-- gc --");
            System.gc();

            TimeUnit.SECONDS.sleep(3);
            System.out.println("-- sleep --");

            System.out.println("-- gc --");
            System.gc();

            TimeUnit.SECONDS.sleep(3);
            System.out.println("-- sleep --");

        } catch (InterruptedException e) {
            System.out.println(e);
        }
    });

    final var ref = queue.remove();
    System.out.println("queue.remove : " + ref.getClass().getSimpleName());

    if (ref instanceof FooRef fooRef) {
        fooRef.clean();
    }

} finally {
    executorService.shutdown();
}

final var ret = executorService.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("term : " + ret);

// Result
// ↓
//ref.get : null
//ref.referesTo : true
//queue.poll : null
//-- gc --
//Finalize!
//-- sleep --
//-- gc --
//queue.remove : FooRef
//Clean!
//-- sleep --
//term : true

Constructors

PhantomReference (T referent, ReferenceQueue<? super T> q)

Creates a new phantom reference that refers to the given object and is registered with the given queue.

var sb = new StringBuilder("abcd");

final var queue = new ReferenceQueue<StringBuilder>();
final var ref = new PhantomReference<>(sb, queue);

System.out.println(ref.get()); // null
System.out.println(ref.refersTo(sb)); // true

System.out.println(queue.poll()); // null

sb = null;
System.gc();

System.out.println(queue.remove()); // java.lang.ref.PhantomReference@6cb107fd

Methods

T get ()

Returns this reference object's referent.

final var sb = new StringBuilder("abcd");

final var queue = new ReferenceQueue<StringBuilder>();
final var ref = new PhantomReference<>(sb, queue);

System.out.println(ref.get()); // null
System.out.println(ref.refersTo(sb)); // true

Methods declared in Reference

clear, clone, enqueue, isEnqueued, reachabilityFence, refersTo

Please see the link below.


Related posts

To top of page