And so the argument is to base your design on a garbage collection scheme that 
may or may not be employed by the currently installed JVM, simply to avoid 
calling removeListener() in the few cases that the lifetime of the listener 
isn't itself tied to the lifetime of the component? That's doesn't seem like 
sound development advice to me. Might as well time some for loops to see how 
many iterations your animation should run for while you're at it.  ;-)

I can potentially see an argument for weak references in a message bus 
framework where there is no component that will be garbage collected and thus 
reclaim the listener as well. So maybe it is worth considering there. But I 
certainly don't see that as a valid argument against using strong listeners 
elsewhere.

On Jun 22, 2010, at 8:59 AM, Noel Grandin wrote:

> 
> It was quite a while ago that I tried, probably around JDK 1.2.2.
> 
> I've only ever run across a couple of memory leaks related to strong
> listeners, and they were dead-easy to find and kill - just follow the
> this$0 reference.
> 
> Weak listeners on the other hand, manifested as UI controls that would
> work for a while, and then stop listening. Which was a major pain to
> find and fix.
> 
> You're right - this is much less of a problem with modern VM's because
> the GC strategy so aggressively collects short-lived objects.
> 
> -- Noel Grandin
> 
> Michael Bushe wrote:
>> How long ago was that experience with weak listeners?  VMs since 1.5
>> (maybe 1.4) would collect a weak listener before the next statement
>> after subscribe() executes.  Try to get a test to pass with a weak
>> listener, it's been a long time since I've seen it.
>> 
>> Even if that were not true, failing after a few minutes is a lot
>> better than a memory leak as slow to close as the BP's Gulf Gusher.
>> 
>> Michael Bushe
>> Principal
>> Bushe Enterprises, Inc.
>> [email protected] <mailto:[email protected]>
>> www.bushe.com <http://www.bushe.com>
>> www.mindfulsoftware.com <http://www.mindfulsoftware.com>
>> www.eventbus.org <http://www.eventbus.org>
>> 
>> 
>> On Tue, Jun 22, 2010 at 2:59 AM, Noel Grandin <[email protected]
>> <mailto:[email protected]>> wrote:
>> 
>>    Hi
>> 
>>    Unfortunately, weak listeners don't "fail fast". In my experience,
>>    with
>>    large applications, weak listeners generally take a couple of
>>    minutes to
>>    fail, which makes them quite painful to track down.
>> 
>>    I think the reason you don't see this issue is because your primary
>>    pattern doesn't use anonymous inner classes.
>> 
>>    But yes, I can see how weak listeners will make life-cycle management
>>    easier when your listeners are methods on a normal class.
>> 
>>    -- Noel Grandin
>> 
>>    Michael Bushe wrote:
>>> In my experience in supporting users of the EventBus, in both
>>    the open
>>> source world and in professional teams, weak references are not
>>    something to
>>> be feared.  This is because:
>>> 1) Weak references fail fast.
>>> 2) Weak reference semantics can be documented.  Make the API's
>>    clear, make
>>> the doc clear, make the examples clear.  Document the
>>    anti-pattern, put it
>>> in the FAQ.
>>> 3) Assume your users are smarter than you might think.
>>     WeakReferences are
>>> pretty easy to understand.  Even if a rookie doesn't understand
>>    them, you
>>> can make it a teachable moment.
>>> 4) WeakReferences are clean and simple.  Managaging listener
>>    lifecycle is
>>> like managing memory in C- it a buggy job that sucks
>>    productivity and bloats
>>> code.
>>> 5) In the 6 years of the EventBus' life, only one user posted a
>>    "this
>>> doesn't work" question because they didn't RTFM.
>>> 
>>> Greg, you didn't detail many of the "number of issues" with
>>    WeakReferences,
>>> so I'm not sure what the perception is, but in my experience
>>    WeakReferences
>>> are better since the lifecycle of the listener is generally (90%+)
>>> equivalent to the lifecycle of the component that defines the
>>    listener.
>>> 
>>> One issue mentioned is the use of an anonymous inner class (a
>>    questionable
>>> pattern anyway), but when annotations are available users
>>    generally use that
>>> more terse route rather than using an anonymous class.  When
>>    developers use
>>> the anonymous class anti-pattern, it fails quickly and they
>>    change it -
>>> often forcing them to think about garbage collection in their
>>    apps, which is
>>> a great thing.  The corollary of using .subscribe(new
>>    XXXSubscriber()) is
>>> even worse when using strong references - without a reference it's
>>> impossible to clean up.
>>> 
>>> I think the encapsulation argument  is extremely weak.  Firstly,
>>    most UI
>>> developers don't care too much about building extensible
>>    classes, but even
>>> when they do, I prefer the opposite effect: Each method that is
>>    annotated as
>>> a subscriber becomes part of the contract of the component.
>>     This is a form
>>> of programming by contract that is very powerful.  It says,
>>    "whenever this
>>> event is fired, I'm going to call this method."  Derived classes can
>>> manipulate the behavior as needed.  Hiding it is equivalent to
>>    the static
>>> final listeners that are all over the Swing framework - it stops
>>    extension
>>> and customization in it's tracks. I went into this pub/sub
>>> programming-by-contract method quite a bit in the
>>> 
>>    
>> article<http://eventbus.org/confluence/pages/viewpage.action?pageId=819222#EventBus%26ApachePivotorRefactoringUIstoUsePub-Sub-Contracts>I
>>> wrote on the EventBus+Pivot.  Lastly, if you don't like that
>>    idea, you
>>> can
>>> easily create private fields that are listeners.
>>> 
>>> The best argument for weak references is that strong references
>>    generally
>>> suck.   Strong references have the opposite effects listed above:
>>> 1) Strong references cause memory "leaks" that don't fail fast.
>>     They fail
>>> very slowly and insiduously.  They are often not caught until
>>    production.
>>> 2) Strong reference issues are hard to document.
>>> 3) Even smart, experienced developers wind up wasting hours or
>>    days tracking
>>> down memory leaks before they find the culprit.
>>> 4) Lifecycle management of listeners is not always easy.  It is
>>    error prone
>>> and bloats code.  Even in the easy cases, it's easily forgotten and
>>> difficult to test for.
>>> 
>>> Note: The Spring ActionScript EventBus shifted (is shifting?) from
>>> defaulting to strong to defaulting to weak.
>>> 
>>> I look forward to seeing how the MessageBus API develops.
>>> 
>>> Michael Bushe
>>> Principal
>>> Bushe Enterprises, Inc.
>>> [email protected] <mailto:[email protected]>
>>> www.bushe.com <http://www.bushe.com>
>>> www.mindfulsoftware.com <http://www.mindfulsoftware.com>
>>> www.eventbus.org <http://www.eventbus.org>
>>> 
>>> On Mon, Jun 21, 2010 at 4:33 PM, aappddeevv
>>    <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>> 
>>>> I think that's fair to do.
>>>> 
>>>> -----Original Message-----
>>>> From: Greg Brown [mailto:[email protected] <mailto:[email protected]>]
>>>> Sent: Monday, June 21, 2010 2:11 PM
>>>> To: [email protected] <mailto:[email protected]>
>>>> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
>>>> annotation
>>>> and an annotation processor for application context message
>>    listener
>>>> 
>>>> It doesn't necessarily need to be used by other parts of the
>>    framework to
>>>> go
>>>> in pivot-core. It just needs to be generally useful and not
>>    have any
>>>> dependencies on the other libraries.
>>>> 
>>>> I'm not sure what else, if anything, I would want it to do - it
>>    is really
>>>> only meant to provide simple intra-application messaging
>>    services without a
>>>> lot of overhead or the need for an external library.
>>>> 
>>>> One advantage to moving it to org.apache.pivot.util is that
>>    listener
>>>> implementations would not require so much typing
>>    (MessageBusListener is
>>>> shorter than ApplicationContextMessageListener). Also, since (like
>>>> WTKXSerializer) it isn't strictly dependent on WTK, it probably
>>    does not
>>>> belong there.
>>>> 
>>>> G
>>>> 
>>>> On Jun 21, 2010, at 11:53 AM, aappddeevv wrote:
>>>> 
>>>> 
>>>>> Yes. But I would leave it there for now. For simple messaging
>>    it is
>>>>> sufficient. More thought is needed. My current thinking is
>>    that unless it
>>>>> used by pivot internally, and hence drives need & evolution,
>>    it could be
>>>>> better to use something else.
>>>>> 
>>>>> 
>>>>> -----Original Message-----
>>>>> From: Greg Brown [mailto:[email protected] <mailto:[email protected]>]
>>>>> Sent: Monday, June 21, 2010 9:52 AM
>>>>> To: [email protected] <mailto:[email protected]>
>>>>> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
>>>>> 
>>>> annotation
>>>> 
>>>>> and an annotation processor for application context message
>>    listener
>>>>> 
>>>>> 
>>>>>> One thing I am finding is for annotations and
>>    auto-registering, that the
>>>>>> machinery dominates the actual messaging code in
>>    ApplicationContext.
>>>>>> 
>>>>> ApplicationContext is large, but the message handling code
>>    itself is
>>>>> 
>>>> pretty
>>>> 
>>>>> small - it is just a few methods:
>>>>> 
>>>>> subscribe()
>>>>> unsubscribe()
>>>>> sendMessage()
>>>>> queueMessage()
>>>>> 
>>>>> I have actually been wondering if it might make sense to move
>>    it to a
>>>>> 
>>>> core
>>>> 
>>>>> class, such as org.apache.pivot.util.MessageBus so that non-UI
>>>>> 
>>>> applications
>>>> 
>>>>> can also use it. The only thing specific to WTK is
>>    queueMessage(), but
>>>>> 
>>>> that
>>>> 
>>>>> could either remain in ApplicationContext and be implemented
>>    in terms of
>>>>> MessageBus, or it could potentially be eliminated - the code
>>    in that
>>>>> 
>>>> method
>>>> 
>>>>> could easily be implemented at the application level.
>>>>> 
>>>>> 
>>>> 
>>>> 
>>> 
>> 
>> 
> 

Reply via email to