Reputation: 11439
I know that the GC collects objects that have no references pointing to the object in question, but what happens in the event of listener objects?
Suppose you have an AnimationDelegate
that listens to data from a DataSupplier
. When the DataSupplier
recieves data and fires off the event to the AnimationDelegate
, the delegate will then invalidate (/update/redraw etc...) a Graphic
. Now say the screen is disabled, removed or, through various means, the graphic can no longer draw and is collected. The AnimationDelegate
is still registered to the DataSupplier
. How will the GC know to collect it? Should one unregister the delegate in the graphics finalize()
method?
Upvotes: 3
Views: 567
Reputation: 15141
It all depends on the JVM you're using and the GC. Most default GC from the JDK use the so called "tracing collectors", which simply start at a given root set of objects and trace all the objects reachable from that set. All the other objects in memory are seen as garbage and deleted. So circular references aren't really a problem unless one of the objects is reachable from the root set.
What is the root set of objects? Well if memory serves right roots can be found in: program registers, local variables in each thread's stack and static variables.
To see if your objects will be GC'd we would know more about the design of your application.
@Edit: Oh and I almost forgot: Memory Management in the JavaHotSpotâ„¢ Virtual Machine. This is a pretty good overview of how it all works.
Upvotes: 2
Reputation: 8523
I'm afraid the answer won't fit the format :) Start with this article by Brian Goetz: he's a perfect person to read if you're interested in GC.
Basically, as soon as object is not reachable from active threads, it's collected. The actual algorithms vary even within one JVM, but the point stays the same: what's not reachable is a garbage. What's reachable is not a garbage. Easy.
GC will not collect the Graphic
in your example, as it's reachable from AnimationDelegate
, which in turn is reachable (via subscription) from DataSupplier
which is supposed to be reachable from some active thread. So the answer will be: your assumptions are wrong; GC will not collect anything here.
To answer your question, unsubscribe everything you don't need.
As @rfeak rightfully says, finalize()
is a big no-no. It's almost impossible to use it properly, and it's way too easy to use it wrong. That said,it's OK to use it as a backup solution when you need to free resources. But generally your application has to be able to work just fine even if finalize()
never gets called.
Upvotes: 3
Reputation: 8214
It will only know if you have removed the references (nulled them out).
However, don't do this on finalize(). Finalize is bad bad bad. There should be other lifecycle methods available for cleaning up listener(observer) type objects.
By the way, observer pattern is notorious for creating memory leaks because the GC couldn't collect due to lingering references.
Upvotes: 0