Search code examples
javagarbage-collectionweak-references

Can WeakReference.get() return non-null after their are no strong references left?


In the following snippet, is it technically possible for widgetRef.get() to return a non-null value after the last strong reachable reference to the Widget has disappeared?

private class Foo {
    private final WeakReference<Widget> widgetRef;

    public Foo(WeakReference<Widget> widgetRef) {
        this.widgetRef = widgetRef;
    }

    public bar() {
        final Widget widget = widgetRef.get();
        if (widget != null) {
            widget.stuff();
        }
    }
}

In other words, can you rely on the garbage collector immediately handling all weak/soft/phantom references as soon as an object becomes weakly reachable?

I believe you cannot rely on the garbage collector doing this, as it may run at any time (and is not running constantly). The WeakReference documentation implies that weak references are only handled when the garbage collector runs:

Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references.

Is there some more explicit documentation about this behaviour?


Solution

  • In the following snippet, is it technically possible for widgetRef,get() to return a non-null value after the last strong reachable reference to the Widget has disappeared?

    It is not only technically possible, it is very likely to happen in practice. You should implement some kind of lifecycle for the object that puts it into a detached/closed state when it ends. If it has a single owner then that owner ought to be responsible for that. If it has multiple owners you can use a counter or a list of owners, essentially implementing reference-counting.

    The garbage collector is only meant to manage memory, not other resources or application-level lifecycles.

    In other words, can you rely on the garbage collector immediately handling all weak/soft/phantom references as soon as an object becomes weakly reachable?

    No.

    Is there some more explicit documentation about this behaviour?

    Which part of the docs you cited do you consider ambiguous for the purpose of your question? The phrasing "at a certain point in time" can be read as "does not guarantee immediate action".