listeners vs risk of memory leaks

The EventRouter class holds references to the listeners. If the listening class is no longer relevant to the application, this reference will prevent garbage collection unless the listener has been removed explicitly. This is fine if the listener and the notifier are in the same container and all will be thrown out together. But in a master-detail form, or in more complicated multi-pane setups with sophisticated event propagation schemes, this becomes very very very much error-prone and I see a real risk of creating memory leaks.

A very easy fix would be to use a Set of WeakReference objects: see
article
– by keeping a Set of WeakReference objects, the listeners would remain garbage-collectable, and the weak reference would simply return null if the listener was indeed garbage-collected.

Looking at the code, the only change required seems to be changing the definition of the “add(listener…” to “add(new WeakReference(listener)…” and the corresponding accesses to a “.get()” . Well spent 5 lines IMHO.

Unfortunately WeakReference does not implement Serializable. Using weak references could thus cause serialization problems. Any ideas on how to resolve those? Could we build a workaround for this by building a custom serialization to EventRouter and “jump over” the weak reference objects while serializing?

I think so. Declaring objects to be “transient” will prevent them from being serialized.

Actually, serialization would go through the weak references and serialize the actual references obtained through .get, since that is what is worth preserving. deserialization would recreate the weak references for the actual references (there is no point in recreating the nulls).

Another concern - what if the event router really
is supposed to be
the only object holding a reference to the event listener? Using a weak reference would cause the listener to be garbage collected and events lost.

The only way I see that for the listener to be the only holder of a reference is if the target is not being displayed (i.e., is not part of any UI structure, and will reinsert itself somewhere in the UI structure upon receiving the event). In all the other scenarios I can dream up, there is a reference to the object (JNDI, ServletContext, session, whatever).

It seems to me that this “in limbo component” scenario is very easy to work around – the coder using this pattern can easily keep tabs of such component, whereas the opposite, requiring all programmers to manually deallocate listeners, seems to be far riskier.

How about [code]

bottomLeftCorner.addComponent(new Button(“+”,
new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
Object id = contactList.addItem();
contactList.setValue(id);
}
}));

[/code]

(cut n paste from
http://vaadin.com/tutorial
)

You are correct. In your example the EventRouter will hold the only reference. Case closed :*)