Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: StackOverflowError



Bjorn Roche wrote:

>Thank-you for the explanation, but that's not quite what I meant.

I gave the "reachable" explanation because it tells how to figure it out by
knowing the relationships between objects.  However, if you don't know the
relationships between the objects, or misunderstand the actual
relationships, then you get a useless answer.

Frankly, I don't think reachability has much bearing on this problem.


>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.

The object b is a JButton.  It isn't in a multicaster, because b is a
sender, not a listener.  That is, b holds a reference to a multicaster (but
see NOTE 1), because a JButton is the source of ActionEvents, not a
recipient.  So b has a field that is its current list of ActionListeners.
The ActionListener al is in b's list of listeners, hence al is reachable
from b.

But, since you removed b from panel, and there are no other references I
can see, then both b and al are unreachable (along with all the other
fields inside b and al).

The JPanel remains reachable, though, and it may have a layout mgr, which
may well retain a reference to b.  The default layout for JPanels is
FlowLayout, which does not retain components.

So the specific answer to this limited scenario is:
  You don't have to remove al from b.

If you subsequently see events delivered to al, then that's pretty
convincing evidence that b *IS* still reachable, and has even been added,
made visible, and become active again.

NOTE 1: JComponent actually uses EventListenerList to hold its
ActionListeners, but al will still be somewhere in that list, or reachable
by some traversal thereof, until you remove it.  But as long as b is
unreachable, so is al, unless you hold another reference to it.


The above appears to be a purely theoretical discussion, though.  Based on
the evidence of your originally posted stack-trace synopsis, it's pretty
clear there *IS* a Component reference, because an event is being pulled
out of the EventQueue and dispatched down a VERY long chain of
AWTEventMulticasters.  For that to happen, there must be a reference to the
Component holding that particular multicaster chain.

It also seems pretty clear that the problem is not a question of
inadvertent recursion, as others have speculated, but of deeply nested
AWTEventMulticasters registered to the Component.  The evidence for this
lies in the source for AWTEventMulticaster.mouseExited():
    public void mouseExited(MouseEvent e) {
        ((MouseListener)a).mouseExited(e);
        ((MouseListener)b).mouseExited(e);
    }

where a and b are declared as:
    protected final EventListener a, b;

Assuming the tree has no cycles, the code given can't recurse indefinitely.
If there were a cycle, you'd get stack-overflow every time, not just when
the multicaster chain-length was excessive.


Based on the stack trace alone, I think you need to investigate exactly how
deep your MouseListener chains are, and do something to limit their growth
in your live referenceable components.

  -- GG


 _______________________________________________
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

This email sent to email@hidden



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.