On Wed, Dec 12, 2012 at 1:22 PM, Andy Seaborne <[email protected]> wrote:
> On 08/12/12 00:03, Claude Warren wrote:
>>
>> I am looking at a case where I need to register a listener to the
>> model.  The default implementation then converts that to a graph
>> listener, so my question applies to both.
>>
>> I don't have a way to detect when my class will be garbage collected
>> (OK, I could use finalize() but that is not guaranteed to be called).
>> My plan was to have a listener registered with the model that would
>> modify my class instance as appropriate.  But when my class instance
>> goes out of scope I want both it and the listener to be garbage
>> collected.
>>
>> This got me wondering if the listener implementation in model (and
>> graph) shouldn't have weak references to the listening entities (e.g.
>> anything registered as a listener).
>>
>> I suppose I can make my listening implementation weakly referred and
>> clean itself up but shouldn't the base implementation of listener do
>> this by default?
>>
>> -- Claude
>>
>
> So there does need to be a weak reference between the listener and your
> class if your class is going to be a candidate for GC.
>
> There is a sort-of related case where there are huge numbers of listeners
> and you want them to be deregistered.  The problem here is to not have a
> massive list of listeners.
>
> The event mechanism is only supposed to be a base level piece of machinery
> where other things can be built on top.
>
> How about a separate ModelListenerAdapter2 that keeps a weak reference to
> the ModelChangedListener (and model m)?
>
> What I'm not sure about is whether building in the WeakReferences into the
> core system is right for everyone.  Plus reported experience with
> WeakReference in the first place (from Jeremy).  If it's general, and
> stable, then fine - an indirection ModelListenerAdapter2 should also work.
>
> If a Weakreference goes null, the listener would deregister itself I
> presume?  This would clearout the underlying listener tracking (a list?) so
> good for long running systems not accumulating dead listeners.
>

I am strongly* against implementing listeners with weak references.

1) It changes the semantics of the listener from "notify object of
event until it is deregistered" to "notify object of event until
object is not referenced by anybody else".  There are plenty of legal
situations in which you can have an object listening for events, and
having no other references keeping it from GC.  An example would be a
listener that calls a static method, such as a Logger.

2) Leads to lazy developers who don't deregister event listeners when
they should, and instead rely on garbage collection.  This can cause
strange bugs where the listener is cleared quickly in a development
environment, but hangs around for a long time in production and causes
the listener to attempt to manipulate objects that have already been
destroyed (happens a lot in GUI programs, where the listener may
attempt to update a window that has been disposed already).

3) Necessitates adding a garbage collection process that clears out
WeakReference objects that have been abandoned.

4) Adds an additional level of indirect, which may have a performance
impact when there are high event rates

Ultimately I think weak references are almost always a hack that
attempts to alleviate the issue of thinking about object lifecycles,
but they ultimately end up causing more problems than they solve.

In spite of all this, if you still want to go down the route of weak
listeners for your application, then it is pretty trivial to build
them on top of the existing interface with your own wrapper object.


-Stephen

* pun intended

Reply via email to