Home arrow static arrow Java Programming [Archive] - Stack Overflow Error
Warning: Creating default object from empty value in /www/htdocs/w008deb8/wiki/components/com_staticxt/staticxt.php on line 51
Java Programming [Archive] - Stack Overflow Error
This topic has 62 replies on 5 pages.    1 | 2 | 3 | 4 | 5 | Next »

Posts:340
Registered: 7/8/04
Stack Overflow Error  
Aug 7, 2004 4:19 AM



 
Hi,

I have program that creates and destoys hundreds of threads, and it crashes sometimes after about 10 or 20 minutes with a stack overflow error, whose source I'm trying to track down. I'm wondering if the garbage collector might not be doing it's work properly, or if I'm not cleaning up after myself correctly. One class in particular concerns me. It has a start method which creates a new thread. That thread often lasts only a few seconds. Hundreds of threads are created and destroyed over the course of about 10 minutes. New threads are created as follows:
	public synchronized void start() {	//kill any previous thread, just in case	mStopped = true;	mThread = new Thread(this);	mThread.start();}

Is there anything incorrect about this? Any reason the garbage collector wouldn't reclaim the memory of dead threads, given that mThread is the only reference to them and that it points to a new address after they die? If that code is not problematic, any general advice for tracking down stack overflow errors?

Thanks,
John
 

Posts:18,384
Registered: 21.03.00
Re: Stack Overflow Error  
Aug 7, 2004 4:23 AM (reply 1 of 62)



 
Hi,

Stack overflow is most often related to recursive calls, and not the gc. (If it was the gc, you would get an out of memory exception). Print the stack trace, and you will most probably find out that it is very long, and that the same sequence is repeating.

/Kaj
 

Posts:18,384
Registered: 21.03.00
Re: Stack Overflow Error  
Aug 7, 2004 4:40 AM (reply 2 of 62)



 
public synchronized void start() {//kill any previous thread, just in casemStopped = true;mThread = new Thread(this);mThread.start();}

And if you think hard enough will will see that the code you have posted is recursive.

/Kaj
 

Posts:340
Registered: 7/8/04
Re: Stack Overflow Error  
Aug 7, 2004 10:06 AM (reply 3 of 62)



 
And if you think hard enough will will see that the
code you have posted is recursive.

kaj,

Thanks for your reply.

Looking over my code, a relay race seems a more apt description than recursion, though I could be wrong. My original post was a simplified for clarity; maybe a few additional details will give you a better idea.

I actually have an event-driven architecture with Observers (which generate events), and Handlers (which process them). The Observers all run in their own threads. After observing events, they send those events to a Handler. In response, the Handler will sometimes create a new Observer (in a new thread). In any case, after the Handler is called the original Observer thread which called it flips a stop switch on its while loop to destroy itself.

Of course, if you follow the chain of events, there are cycles. That is, the original Observer object (the one started when the app begins and which destroys itself after sending off the first event) will eventually get restarted (though obviously as a new Thread). Because it is a new thread, I would think this should avoid the problems associated with recursion. Am I wrong here? Any other thoughts?

Thanks again,
John
 

Posts:3,081
Registered: 2/15/99
Re: Stack Overflow Error  
Aug 7, 2004 10:12 AM (reply 4 of 62)



 
If you get a stack overflow, overwhelming odds are you have infinite or ridiculously deep recursion. Don't waste your time looking for other causes first. No, gc is not broken.

kajbj's Reply 1 above is right on the money: Print The Stack Trace.
 

Posts:340
Registered: 7/8/04
Re: Stack Overflow Error  
Aug 7, 2004 10:15 AM (reply 5 of 62)



 
Point taken.

How do I do that?

Thanks,
John
 

Posts:18,384
Registered: 21.03.00
Re: Stack Overflow Error  
Aug 7, 2004 10:17 AM (reply 6 of 62)



 
Hi,

Why don't test? Add the following line of code to the top of your run method (in runnable, or thread)
    new Exception().printStackTrace();


Then you will see a stack trace each time a new thread is started. If the is a cycle, then it's recursive, event if the cycle is long, and that will make the stack grow till you get a stack overflow exception.

/Kaj

 

Posts:3,081
Registered: 2/15/99
Re: Stack Overflow Error  
Aug 7, 2004 10:25 AM (reply 7 of 62)



 
    public static void main(String args[])    {        try {            ...your program here...        } catch (Throwable e) {            e.printStackTrace();        }    }

If you use some log package, it might have a different preferred way of printing a stack trace (e.g. log.print("uh oh", e);)

If you are starting threads, you'll need to wrap their run()'s bodies around try/catch similarly. Ditto for doGet()/doPost()/etc of servlets.

If you already have try/catch blocks around the code, check that all of them print the stack trace.

Generally catching Throwable is a bit dodgy (Exception may be preferred by some), but necessary for tracking some kinds of problems. I shamelessly always catch Throwables at the "top level of processing" (main(), run(), ...)
 

Posts:3,081
Registered: 2/15/99
Re: Stack Overflow Error  
Aug 7, 2004 10:29 AM (reply 8 of 62)



 
Oh, if the recursion is gradual (as opposed to some thread suddenly going wild and recursing 10000 levels in a fraction of a second), run the program for a while, then hit control-backslash (Unix) or control-break (Windos). That gives stack traces of all threads to the console. If one thread dump has dozens of levels, that's your bad boy.
 

Posts:340
Registered: 7/8/04
Re: Stack Overflow Error  
Aug 7, 2004 10:29 AM (reply 9 of 62)



 
Generally catching Throwable is a bit dodgy (Exception
may be preferred by some), but necessary for tracking
some kinds of problems. I shamelessly always catch
Throwables at the "top level of processing" (main(),
run(), ...)

I will try that right now.

Also, why is it shameless to catch Throwables at the top level?

John
 

Posts:18,384
Registered: 21.03.00
Re: Stack Overflow Error  
Aug 7, 2004 10:35 AM (reply 10 of 62)



 
Because there is probably nothing you can do about that exception at that time. What would you e.g. do about the stack overflow? There is nothing you can do. Just print the cause and terminate. The error should then be resolved by a developer (but it would hopefully been found during testing)

/Kaj
 

Posts:3,081
Registered: 2/15/99
Re: Stack Overflow Error  
Aug 7, 2004 10:40 AM (reply 11 of 62)



 
Catching Throwables is a bit naughty because they include things like InternalError, VirtualMachineError, OutOfMemoryError, ... It's up to luck whether even e.printStackTrace() will work after one of those. It can be impossible to recover from some Throwables.

Don't catch Throwables or Errors in "normal code", Exceptions at most. But perhaps make an exception to that rule in the "top level of processing" to get a shot at logging StackOverflowErrors etc.
 

Posts:340
Registered: 7/8/04
Re: Stack Overflow Error  
Aug 7, 2004 11:12 AM (reply 12 of 62)



 
run the program for a
while, then hit control-backslash (Unix) or
control-break (Windos). That gives stack traces of all
threads to the console. If one thread dump has dozens
of levels, that's your bad boy.

Yes, this is what I want to do, b/c sometimes it can take up to an hour to see the stack overlow. I'm on Windows... When I do ctrl-break, I get a "full thread dump," which i'm guessing is different than a stack trace, as there are no levels anywhere to be seen. Is there another ctrl sequence i should try?

thanks again,
John
 

Posts:3,081
Registered: 2/15/99
Re: Stack Overflow Error  
Aug 7, 2004 11:18 AM (reply 13 of 62)



 
Control-break should give stack dumps of all threads (except maybe some internal threads, gc etc, that don't execute Java):
public class t{    static void one() { two(); }    static void two() { three(); }    static void three() { try { Thread.sleep(10000); } catch (Exception e) {} }     public static void main(String args[])    {	one();    }} "main" prio=5 tid=0x00235d68 nid=0x5bc waiting on condition [0x0006f000..0x0006fc3c]        at java.lang.Thread.sleep(Native Method)        at t.three(t.java:6)        at t.two(t.java:5)        at t.one(t.java:4)        at t.main(t.java:10)
 

Posts:37,103
Registered: 3/30/99
Re: Stack Overflow Error  
Aug 7, 2004 11:22 AM (reply 14 of 62)



 
Is this code from your first post
public synchronized void start() {...} 
in a class that implements Runnable or that extends Thread? If it extends thread, then there's your infinite recursion. If it's a Runnable, then it's probably somewhere else, but, as others have said, it's almost certainly recursion.

Is the above being called from inside a Thread/Runnable's run() method? If so, that's recursion--that run() method will never end, and more and more will just get piled on top of it.
 
This topic has 62 replies on 5 pages.    1 | 2 | 3 | 4 | 5 | Next »