What will GC do if there is a two level soft referenced object

189 views Asked by At

I know in Java we have concept of soft reference. What if:

1) There is a soft reference "sf" refer to an object A

2) In object A, it has a strong reference refers to object B

3) object A & B are not referenced anywhere else.

By definition, object A and object B are both "softly reachable", right?

Then say we are running out of memory now, GC kicks in. Is it possible that GC will recycle object B but not object A?

If that's the case, later if we want to access object B through "sf", it will be null. How java avoid such case to happen?

I don't see any explain in java doc.

3

There are 3 answers

14
Stephen C On

Then say we are running out of memory now, GC kicks in. Is it possible that GC will recycle object B but not object A?

No. The GC will not break strong references in reachable objects. (It will, of course break references in unreachable objects as part of the reclamation process. But you can't observe that happening ... because to observe it, you'd need the object to still be reachable.)

This is a consequence of this statement in the javadoc for the java.lang.ref package.

"Finally, an object is unreachable, and therefore eligible for reclamation, when it is not reachable in any of the above ways."

... where "the above ways" includes strong, soft, weak and phantom reachability.

The two highlighted words mean that eligibility for reclamation is a consequence of being in the unreachable state. Since none of the other states mention reclamation eligibility, we conclude that non-reachability is a precondition for reclamation.

This certainly aligns with common sense. If (hypothetically) the GC was allowed to "null out" strong references in reachable objects, it would be impossible for an application to safely work with objects after they had gotten into this state. (Consider the case where the nulled-out reference was in an instance of a library class ...)

4
nsfyn55 On

From the docs:

"An object is softly reachable if it is not strongly reachable but can be reached by traversing a soft reference."

"An object is strongly reachable if it can be reached by some thread without traversing any reference objects"

I think thats pretty clear. B is softly reachable because it is only reachable by traversing a soft reference.

Said Docs

4
Voo On

I think a short introduction on how tracing GCs basically work should clear things up.

A tracing GC (the ones used in Java and .NET all fall into that category) has a set of so called root pointers, those are global variables (in java that means static variables of classes) and all live variables in the stackframes. The GC traverses these and marks all objects that are alive, i.e. reachable through references from at least one of the root pointers. When it has finished, all live variables have been marked and the rest can be garbage collected.

A soft reference now can be handled in two different ways: a) we follow the soft reference and mark all objects in it or b) we don't. What exactly happens is at the mercy of the given JVM implementation, but after that has been decided there's no other difference.

Hence there are two possible scenarios:

  • The GC follows the soft reference to A in which case none of the two objects will be GCed.
  • The GC doesn't follow the soft reference to A (and there are no hard references to it). A is GCed, B is GCed if no live object has a reference to it.