xarax said:
Only *after* the TestA instance
becomes eligible for reclaim will GC notice that its TestB instance
field was the last strong reference for the "b" object. The
determination of GC eligibility is an incremental process.
Are you using the expression "eligible for reclaim" in a technical sense,
defined as part of some Java spec somewhere ? I can't find anywhere that does
so, but could very easily have missed something.
If so then I can understand how the necessity for precision for describing the
lifetime of an object in the presence of finalisation could lead to terminology
that makes what you say exactly correct.
But if not, then I think it's wrong. Ignoring finalisation for a moment, in
what I would call "normal" terminology, an object becomes eligible for reclaim
once there is no longer any path leading from a root, such as a thread's stack
frame, to that object. (I'm also ignoring weak/soft/phantom references here).
Hence, at the moment where any one object becomes eligible, all other objects
that are only reachable via that object also become eligble -- by definition.
What may change is whether and how an actual GC algorithm can *detect* that
eligibility. Algorithms in the broad category including mark-and-sweep,
copying, etc will in one sense discover that both objects are unreachable at
the same time. In another sense they never discover that any object is
unreachable -- they are only interested in ones that are reachable, everything
else is just unintialised RAM. GC algorithms which use some variant of
reference counting *do* have the incremental nature that you describe -- the GC
actively follows trains of unreachability: "aha this is unreachable. Good. So
that means *this* is unreachable too". And so on...
When you factor finalisation into the picture then it gets more complicated,
and the terminology doesn't seem to be particularly well established. However,
one way to see it is that finalisation breaks the link between being
"unreachable from a root" and "eligible for reclaim". Another way of seeing it
(which matches the language of the JLS2 rather better) is that the system
automatically moves finalisable objects which are not otherwise reachable into
a state where they are only reachable by other objects in that state and by the
finalisation process (zero, one, or more threads). In either case (as I read
the rather opaque text) finalisation does introduce something rather like the
incremental process that you describe in that no object becomes eligible for
reclaim until it, and all chains of references to it, have been finalized
without making it reachable again.
I suspect, though, that you know all this perfectly well, and what we have here
is a difference in terminology rather than a different understanding of how
real GC algorithms work. Could you clarify please ?
-- chris