Say I've got a button. I register a listener on that button. After I am
done with it, I remove it from the parent, and delete my references to it.
Do I still have a listener registered with the system? What if I delete my
references to the listener? I did not consider how Java solves this problem
when I started coding (I solve it with Weak refereces), but I assumed Java
had some solution to it. Does it not?
An object reference becomes eligible for reclamation (susceptible to GC)
when all references to it are gone from every active object. Every
reference in a static or instance field is reachable, unless the object
having that field is unreachable.
Since a Thread is an object, and a Thread has a stack, objects in local
variables in any active stack-frame are also reachable.
So if you have a listener registered on a component, and the component is
reachable, then all the component's registered listeners are also reachable.
If you remove a listener from a component, then the component no longer
holds that listener's reference, but other objects in other contexts still
might. So whether a listener is reachable or not depends on what the
entire program is doing, and where your code is holding references.
Thank-you for the explanation, but that's not quite what I meant. Perhaps
an example will clarify.
Say I create a button, register a listner and add the button to a panel:
ActionListner al = new ActionListener() {
//some stuff
};
JButton b = bew JButton();
b.addActionListener( al );
JPanel panel = new JPanel();
panel.add( b );
Now, say I am done with my button and I do this:
panel.removeAll();
b = null;
al = null;
My question is: do I have to explicitly remove my action listener from the
button in order to reclaim all my resources? I have never heard anything
to that effect, but your response made me think maybe I do. Some
intelligence would be required on the part of AWT to know that b did not
need be in the multicaster anymore.
I suspect that the problem you think you're solving with weak references
isn't solving anything, but may well be the cause of the problem. Since
you didn't supply any code or explanation other than "I solve it with weak
references", all we can do is guess about what you're actually doing.
Weak references aren't listeners, so you can't register listeners weakly.
Therefore, all registered listeners are strongly reachable, and any weak
references held by a particular registered listener are irrelevant to the
depth of the AWTEventMulticaster tree.
Sorry for the confusion. I have my own objects with their own listeners. I
use weak references to keep track of lists listeners, reducing the need to
unregister the listeners. It has nothing to do with the
AWTEventMulticaster and is tangential to this discussion -- I just thought
I would comment that this strategy could be used to reduce the need to
unregister listeners.
If you define a listener proxy that holds a weak reference to the real
listener, the proxy itself is still strongly reachable from whatever
components it's registered as a listener to. The fact that the event
"dead-ends" at the proxy when the weak-ref goes away doesn't change
anything about the COMPONENT's registered listeners. In short, using a
proxy won't change the depth of the component's listener tree, and that's
the problem. The weakness of the reference is pointing in the wrong
direction, or isn't close enough to matter.
being unregistered. You have to find these large herds of listeners and
reduce their number, otherwise you're not solving the problem.
I am doing this now, but I doubt there is any one huge culprit.
I suggest creating a diagnostic tool for finding the depth of
AWTEventMulticasters. It will take some use of the reflection API, because
the visibility of the fields in Component et al. is restricted.
I also recommend a detailed diagnostic tool (could be the same class as the
depth-finder) that can print out the type of every "leaf" listener seen in
a multicaster tree. That should offer a big clue about where the listeners
are all coming from, and may offer hints about possible remedies.
There may be more than one culprit, which is why reducing the stack-size
causes the problem to occur more often. But if you don't know how deep the
listeners are really nesting, nor their type, and especially if you don't
remove() any (as distinct from letting weak-refs degrade), then it's
anyone's guess as to how deep they're actually going.
You can approximate the depth by looking at how many times you see
mouseExited() or whatever in your actual StackOverflowError stack-trace.
Send the trace through 'grep' and 'wc' to get a count. Or paste into a
text-file and ask for a line-count.
thanks for the suggestions.
bjorn
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden