Why is it possible to recover from a StackOverflowError? - java

I'm surprised at how it is possible to continue execution even after a StackOverflowError has occurred in Java.
I know that StackOverflowError is a sublass of the class Error.
The class Error is decumented as "a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch."
This sounds more like a recommendation than a rule, subtending that catching a Error like a StackOverflowError is in fact permitted and it's up to the programmer's reasonability not to do so. And see, I tested this code and it terminates normally.
public class Test
{
public static void main(String[] args)
{
try {
foo();
} catch (StackOverflowError e) {
bar();
}
System.out.println("normal termination");
}
private static void foo() {
System.out.println("foo");
foo();
}
private static void bar() {
System.out.println("bar");
}
}
How can this be? I think by the time the StackOverflowError is thrown, the stack should be so full that there is no room for calling another function. Is the error handling block running in a different stack, or what is going on here?

When the stack overflows and StackOverflowError is thrown, the usual exception handling unwinds the stack. Unwinding the stack means:
abort the execution of the currently active function
delete its stack frame, proceed with the calling function
abort the execution of the caller
delete its stack frame, proceed with the calling function
and so on...
... until the exception is caught. This is normal (in fact, necessary) and independent of which exception is thrown and why. Since you catch the exception outside of the first call to foo(), the thousands of foo stack frames that filled the stack have all been unwound and most of the stack is free to be used again.

When the StackOverflowError is thrown, the stack is full. However, when it's caught, all those foo calls have been popped from the stack. bar can run normally because the stack is no longer overflowing with foos. (Note that I don't think the JLS guarantees you can recover from a stack overflow like this.)

When the StackOverFlow occurs, the JVM will pop down to the catch, freeing the stack.
In you example, it get rids of all the stacked foo.

Because the stack doesn't actually overflow. A better name might be AttemptToOverflowStack. Basically what it means is that the last attempt to adjust the stack frame errs because there isn't enough free space left on the stack. The stack could actually have lots of space left, just not enough space. So, whatever operation would have depended upon the call succeeding (typically a method invocation), never gets exectued and all that is left is for the program to deal with that fact. Which means that it is really no different from any other exception. In fact, you could catch the exception in the function that is making the call.

As has already been answered, it is possible to execute code, and in particular to call functions, after catching a StackOverflowError because the normal exception handling procedure of the JVM unwinds the stack between the throw and the catch points, freeing stack-space for you to use. And your experiment confirms that is the case.
However, that is not quite the same as saying that it is, in general, possible to recover from a StackOverflowError.
A StackOverflowError IS-A VirtualMachineError, which IS-AN Error. As you point out, Java provides some vague advice for an Error:
indicates serious problems that a reasonable application should not try to catch
and you, reasonably, conclude that should sounds like catching an Error might be OK in some circumstances. Note that performing one experiment does not demonstrate that something is, in general, safe to do. Only the rules of the Java language and the specifications of the classes you use can do that. A VirtualMachineError is a special class of exception, because the Java Language Specification and the Java Virtual Machine Specification provide information about the semantics of this exception. In particular, the latter says:
A Java Virtual Machine implementation throws an object that is an instance of a subclass of the class VirtualMethodError when an internal error or resource limitation prevents it from implementing the semantics described in this chapter. This specification cannot predict where internal errors or resource limitations may be encountered and does not mandate precisely when they can be reported. Thus, any of the VirtualMethodError subclasses defined below may be thrown at any time during the operation of the Java Virtual Machine:
...
StackOverflowError: The Java Virtual Machine implementation has run out of stack space for a thread, typically because the thread is doing an unbounded number of recursive invocations as a result of a fault in the executing program.
The crucial problem is that you "cannot predict" where or when a StackOverflowError will be thrown. There are no guarantees about where it will not be thrown. You can not rely on it being thrown on entry to a method, for example. It could be thrown at a point within a method.
This unpredictability is potentially disastrous. As it can be thrown within a method, it could be thrown part way through a sequence of operations that the class considers to be one "atomic" operation, leaving the object in a partially modified, inconsistent, state. With the object in an inconsistent state, any attempt to use that object could result in erroneous behaviour. In all practical cases you can not know which object is in an inconsistent state, so you have to assume that no objects are trustworthy. Any recovery operation or attempt to continue after the exception is caught could therefore have erroneous behaviour. The only safe thing to do is therefore to not catch a StackOverflowError, but rather to allow the program to terminate. (In practice you might attempt to do some error logging to assist troubleshooting, but you can not rely on that logging operating correctly). That is, you can not reliably recover from a StackOverflowError.

Related

Throwing always the same exception instance in Java

It was always told me that Java exception handling is quite expensive.
I'm asking if is it a good practice creating an exception instance of a specific type at the beginning of the program and without creating a new one, throwing always the same exception object.
I just want to make an example. Common code:
if (!checkSomething(myObject))
throw new CustomException("your object is invalid");
alternative:
static CustomException MYEXP = new CustomException("your object is invalid");
//somewhere else
if (!checkSomething(myObject))
throw MYEXP;
Of course, I'm doing some assumptions here:
MyCustomException has no parameters
client code, whenever is a good practice or not, is heavlily based on exception handling and refactoring is not an option.
So questions are:
Is this a good practice?
Does this damage some JVM mechanism?
If 1 is yes, there is the possibility of a performance gain? (I think not, but not sure)
If 1 and 3 are yes, why is not sponsored as practice?
If 1 is no, why Martin Odersky told in his introduction to Scala that this is how Scala works in some cases? (At minute 28.30 he tolds that break is implemented has throwing an exception, audience says that this is time consuming and he replies that exception is not created every time)Fosdem 2009
I hope this is not a idle/stupid question, I'm curious about this. I think that real cost in exception handling is handling and not creation.
edit
Added reference of precise discussion on FOSDEM presentation
disclaimer: none of my code works like proposed and I have no intention to manage exception like this, I'm just doing a "what-if" question and this curiosity is generated from the affermation that video. I thought: if it's done in Scala, why is not in Java?
No, don't do that. The expensive part is not handling the exception, it is generating the stacktrace. Unfortunately the stacktrace is also the useful part. If you throw a saved exception you will be passing on a misleading stacktrace.
It could be that within the implementation of Scala there are situations where it makes sense to do this. (Maybe they are doing something recursive and want to generate an exception object upfront so in case they run out of memory they can still produce an exception.) They also have a lot of information about what they're doing so they have a better chance of getting it right. But optimizations made by JVM language implementors are a very special case.
So you wouldn't be breaking anything, unless you think providing misleading information constitutes breakage. It seems like a big risk to me.
Trying out Thomas Eding's suggestion for how to create an exception with no stacktrace seems to work:
groovy:000> class MyException extends Exception {
groovy:001> public Throwable fillInStackTrace() {}}
===> true
groovy:000> e = new MyException()
===> MyException
groovy:000> Arrays.asList(e.stackTrace)
===> []
Also check out the JLS:
The NullPointerException (which is a kind of RuntimeException) that is
thrown by method blowUp is not caught by the try statement in main,
because a NullPointerException is not assignable to a variable of type
BlewIt. This causes the finally clause to execute, after which the
thread executing main, which is the only thread of the test program,
terminates because of an uncaught exception, which typically results
in printing the exception name and a simple backtrace. However, a
backtrace is not required by this specification.
The problem with mandating a backtrace is that an exception can be
created at one point in the program and thrown at a later one. It is
prohibitively expensive to store a stack trace in an exception unless
it is actually thrown (in which case the trace may be generated while
unwinding the stack). Hence we do not mandate a back trace in every
exception.
Q1. Is this a good practice?
Not in my book. It adds complexity and hinders diagnostic (see my answer to Q2).
Q2. Does this damage some JVM mechanism?
You won't get a meaningful stack trace from such an exception object.
Q3. If 1 is yes, there are performances gain? (I think not, but not sure)
Q4. If 1 and 3 are yes, why is not sponsored as practice?
Due to the problems outlined above.
Q5. If 1 is no, why Martin Odersky told in his introduction to Scala that this is how Scala works in some cases? (sorry, but I can't remember the context of this affirmation at the moment) Fosdem 2009
Hard to answer without the context.
You can do that, but the exception
must have no stacktrace, since the initial stacktrace will only serve to confuse in subsequent uses.
must not accept suppressed exceptions. if multiple threads try to add suppressed exceptions to it, things will corrupt.
So your exception constructor must do
super(msg, cause, /*enableSuppression*/false, /*writableStackTrace*/false);
see http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#Throwable%28java.lang.String,%20java.lang.Throwable,%20boolean,%20boolean%29
Now, is it useful? Yes, otherwise why would these two boolean flags exist in the first place?:)
In some complicated cases, exception can be used as a flow control device, it may produce a simpler, faster code. Such exceptions are known as "control exceptions".
If an exception is really to indicate something exceptionally wrong with the program, then use the traditional exception.
Even though Exceptions are relatively expensive and should be kept to a minimum, they don't cost so much that you should do obtuse things "for performance purposes" This is so often a bad excuse that it is even considered by some that premature optimisation should be avoided at all costs. While that is not entirely true, you can measure how slow exceptions are.
long start = System.nanoTime();
int exceptionCount = 0;
for (int i = 0; i < 20000; i++)
try {
int j = i / (i & 1);
} catch (ArithmeticException ae) {
exceptionCount++;
}
long time = System.nanoTime() - start;
System.out.printf("Each exception took average of %,d ns%n", time / exceptionCount);
prints what I believe is a reasonable estimate.
Each exception took average of 3,064 ns
Note: as the number of loops increases, the Exception is optimised away. i.e. for a 10x the iterations
Each exception took average of 327 ns
and for 10x more
Each exception took average of 35 ns
and for 10x more
Each exception took average of 5 ns
If the exception is thrown enough, it appears the JIT is smart enough to optimise the Exception away.

What's a reasonable lifespan to expect of a java exception?

Is it reasonable to maintain a reference to an exception for later use, or are there pitfalls involved with keeping a reference to an exception for significantly longer than the throw/catch interaction?
For example, given the code:
class Thing {
private MyException lastException = ...;
synchronized void doSomethingOrReportProblem() {
try {
doSomething();
} catch (MyException e) {
if (seemsLikeADifferentProblem(e, lastException)) {
reportProblem(e);
}
lastException = e;
}
}
}
Assuming that my program creates a Thing with a lifespan as long as the JVM, are there any correctness issues involved with Thing maintaining a lingering reference to lastException? And has this changed at all in JDK7? (Looking at the source code to Throwable in OpenJDK7, it seems like there's a new four-argument public constructor that wasn't in JDK6 that can create a Throwable without invoking fillInStackTrace() at construction time.)
If any of the chained exceptions under MyException had references to objects, yes, this would prevent those objects from getting garbage collected, but assuming I'm ok with that, are there any traps to beware?
A Throwable is a full-fledged Java object and will persist as long as someone has a reference to it. It's been awhile since I was inside Throwable, but I can't think of anything it might in turn be retaining a reference to other than (just maybe) the classes of the methods in the stack trace. The stack trace itself does consume a non-trivial amount of storage, however.
So it's really no different from any other moderately large object. And retaining a single exception for the life of the JVM would not seem to be at all out of line. (If you kept a record of ALL exceptions, that might be a bit much.)
I would suggest that you should basically treat it as you would any object with some "native code/storage on the back end". If you need to keep references to a few Exceptions, e.g. to "remember" where a particular method was called from etc, then don't be afraid to do so. On the other hand, don't keep on to hundreds of thousands of them without building in some way of 'monitoring the situation'.
There are 2 common cases where references to Exceptions are held beyond their immediate programatic relevance:
When being passed to logging frameworks
When being propagated out of the container context, typically being returned to a remote application after being adapted to a suitable form

Throwing a new exception while throwing an old exception

If a destructor throws in C++ during stack unwinding caused by an exception, the program terminates. (That's why destructors should never throw in C++.) Example:
struct Foo
{
~Foo()
{
throw 2; // whoops, already throwing 1 at this point, let's terminate!
}
};
int main()
{
Foo foo;
throw 1;
}
terminate called after throwing an instance of 'int'
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
If a finally block is entered in Java because of an exception in the corresponding try block and that finally block throws a second exception, the first exception is silently swallowed. Example:
public static void foo() throws Exception
{
try
{
throw new Exception("first");
}
finally
{
throw new Exception("second");
}
}
public static void main(String[] args)
{
try
{
foo();
}
catch (Exception e)
{
System.out.println(e.getMessage()); // prints "second"
}
}
This question crossed my mind: Could a programming language handle multiple exceptions being thrown at the same time? Would that be useful? Have you ever missed that ability? Is there a language that already supports this? Is there any experience with such an approach?
Any thoughts?
Think in terms of flow control. Exceptions are fundamentally just fancy setjmp/longjmp or setcc/callcc anyway. The exception object is used to select a particular place to jump to, like an address. The exception handler simply recurses on the current exception, longjmping until it is handled.
Handling two exceptions at a time is simply a matter of bundling them together into one, such that the result produces coherent flow control. I can think of two alternatives:
Combine them into an uncatchable exception. It would amount to unwinding the entire stack and ignoring all handlers. This creates the risk of an exception cascade causing totally random behavior.
Somehow construct their Cartesian product. Yeah, right.
The C++ methodology serves the interest of predictability well.
You can chain exceptions. http://java.sun.com/docs/books/tutorial/essential/exceptions/chained.html
try {
} catch (IOException e) {
throw new SampleException("Other IOException", e);
}
You can also have a try catch inside your finnally too.
try{
}catch(Exception e){
}finally{
try{
throw new SampleException("foo");
}catch(Exception e){
}
}
Edit:
Also you can have multiple catches.
I don't think multiple exceptions would be a good idea, because an exception is already something you need to recover from. The only reason to have more than one exception I can think of is if you use it as part of your logic (like multiple returns), wich would be deviating from the original purpose of the idea of the Exception.
Besides, how can you produce two exceptions at the same time?
Could a programming language handle multiple exceptions? Sure, I don't see why not. Would this be useful? No, I would say it would not be. Error handling and resumption is very hard as it is - I don't see how adding combinatorial explosion to the problem would help things.
Yes, it is possible for a language to support throwing multiple exceptions at a time; however, that also means that programmers need to handle multiple exceptions at a time as well, so there is definitely a tradeoff. I have heard of languages that have this although I am having trouble coming up with the list off the top of my head; I believe LINQ or PLINQ may be one of those languages, but I don't quite remember. Anyway, there are different ways that multiple exceptions can be thrown... one way is to use exception chaining, either by forcing one exception to become the "cause" or "previouslyProgatingException" of the other, or to bottle all of the exceptions up into a single exception representing the fact that multiple exceptions have been thrown. I suppose a language could also introduce a catch clause that lets you specify multiple exception types at once, although that would be a poor design choice, IMHO, as the number of handlers is large enough as is, and that would result in an explosion of catch clauses just to handle every single possible combination.
C++ std::exception_ptr allows you store exceptions. So it should be possible to embed exceptions in other exceptions and give you the impression that you have the stack on thrown exceptions. This could be useful if you want to know the root cause of the actual exception.
One situation where multiple thrown exceptions in parallel might be useful, is unit testing with JUnit:
If a test fails, an exception is thrown (either produced by code under test or an assertion).
Each #After method is invoked after the test, whether the test fails or succeeds.
If an After method fails, another exception is thrown.
Only the exception thrown in the After method is displayed in my IDE (Eclipse) for the test result.
I know that JUnit notifies its test listeners about both exceptions, and when debugging a test in Eclipse I can see the first exception appearing in the JUnit view, only to be replaced by the second exception shortly after.
This problem should probably be resolved by making Eclipse remember all notifications for a given test, not only the last one. Having "parallel exceptions", where the exception from the finally does not swallow the one from the try, would solve this issue too.
If you think about it, the situation you've described has Exception("First") as the root cause of Exception("second"), conceptually. The most useful thing for the user would probably be to get a stack dump showing a chain in that order...
In managed platforms, I can think of situations where it might be useful to have a disposer "elevate" an exception to something which is stronger, but not totally fatal to an application. For example, a "command" object's disposer might attempt to unwind the state of its associated connection to cancel any partially-performed commands. If that works, the underlying code may attempt to do other things with the connection. If the attempted "cancel" doesn't work, the exception should probably propagate out to the level where the connection would have been destroyed. In such a case, it may be useful for the exception to contain an "inner exception", though the only way I know to achieve that would be to have the attempted unwinding in a catch block rather than a "finally" block.

Is returning null after exception is caught bad design [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return. The following code snippet illustrates my problem.
public Object getObject(){
try{
...
return object;
}
catch(Exception e){
//I have to return something here but what??
return null; // is this a bad design??
}
}
So my questions are:
Is return null bad design?
If so what is seen as a cleaner solution??
thanks.
I would say don't catch the exception if you really can't handle it. And logging isn't considered handling an error. Better to bubble it up to someone who can by throwing the exception.
If you must return a value, and null is the only sensible thing, there's nothing wrong with that. Just document it and make it clear to users what ought to be done. Have a unit test that shows the exception being thrown so developers coming after you can see what the accepted idiom needs to be. It'll also test to make sure that your code throws the exception when it should.
I always come across the same problem that when an exception is caught in a function that has a non-void return value I don't know what to return.
If you don't know what to return, then it means that you don't know how to handle the exception. In that case, re-throw it. Please, don't swallow it silently. And please, don't return null, you don't want to force the caller of the code to write:
Foo foo = bar.getFoo();
if (foo != null) {
// do something with foo
}
This is IMHO a bad design, I personally hate having to write null-checks (many times, null is used where an exception should be thrown instead).
So, as I said, add a throws clause to the method and either totally remote the try/catch block or keep the try/catch if it makes sense (for example if you need to deal with several exceptions) and rethrow the exception as is or wrap it in a custom exception.
Related questions
How to avoid “!= null” statements in Java?
Above all I prefer not to return null. That's something that the user has to explicitly remember to handle as a special case (unless they're expecting a null - is this documented). If they're lucky they'll deference it immediately and suffer an error. If they're unlucky they'll stick it in a collection and suffer the same problem later on.
I think you have two options:
throw an exception. This way the client has to handle it in some fashion (and for this reason I either document it and/or make it checked). Downsides are that exceptions are slow and shouldn't be used for control flow, so I use this for exceptional circumstances (pun intended)
You could make use of the NullObject pattern.
I follow a coding style in which I rarely return a null. If/when I do, that's explicitly documented so clients can cater for it.
Exceptions denote exceptional cases. Assuming your code was supposed to return an object, something must have gone wrong on the way (network error, out of memory, who knows?) and therefore you should not just hush it by returning null.
However, in many cases, you can see in documentation that a method returns a null when such and such condition occurs. The client of that class can then count on this behaviour and handle a null returned, nothing bad about that. See, in this second usage example, it is not an exceptional case - the class is designed to return null under certain conditions - and therefore it's perfectly fine to do so (but do document this intended behaviour).
Thus, at the end of the day, it really depends on whether you can't return the object because of something exceptional in your way, or you simply have no object to return, and it's absolutely fine.
I like the responses that suggest to throw an exception, but that implies that you have designed exception handling into the architecture of your software.
Error handling typically has 3 parts: detection, reporting, and recovery. In my experience, errors fall into classes of severity (the following is an abbreviated list):
Log for debug only
Pause whatever is going on and report to user, waiting for response to continue.
Give up and terminate the program with an apologetic dialogue box.
Your errors should be classified and handling should be as generically and consistently as possible. If you have to consider how to handle each error each time you write some new code, you do not have an effective error handling strategy for your software. I like to have a reporting function which initiates user interaction should continuation be dependent on a user's choice.
The answer as to whether to return a null (a well-worn pattern if I ever saw one) then is dependent on what function logs the error, what can/must the caller do if the function fails and returns the null, and whether or not the severity of the error dictates additional handling.
Exceptions should always be caught by the controller in the end.
Passing a <null> up to the controller makes no sense.
Better to throw/return the original exception up the stack.
It's your code and it's not bad solution. But if you share your code you Shoudn't use it because it can throw unexpected exception (as nullpointer one).
You can of course use
public Object getObject() throws Exception {}
which can give to parent function usable information and will warn that something bad can happen.
Basically I would ditto on Duffymo, with a slight addition:
As he says, if your caller can't handle the exception and recover, then don't catch the exception. Let a higher level function catch it.
If the caller needs to do something but should then appropriately die itself, just rethrow the exception. Like:
SomeObject doStuff()
throws PanicAbortException
{
try
{
int x=functionThatMightThrowException();
... whatever ...
return y;
}
catch (PanicAbortException panic)
{
cleanUpMess();
throw panic; // <-- rethrow the exception
}
}
You might also repackage the exception, like ...
catch (PanicAbortException panic)
{
throw new MoreGenericException("In function xyz: "+panic.getMessage());
}
This is why so much java code is bloated with if (x!=null) {...} clauses. Don't create your own Null Pointer Exceptions.
I would say it is a bad practice. If null is received how do I know if the object is not there or some error happened?
My suggestion is
never ever return NULL if the written type is an array or
Collection. Instead, return an empty Collection or an empty array.
When the return type is an object, it is up to you to return null depending on the scenario. But never ever swallow an exception and return NULL.
Also if you are returning NULL in any scenario, ensure that this is documented in the method.
As Josha Blooch says in the book "Effective Java", the null is a keyword of Java.
This word identifies a memory location without pointer to any other memory location: In my opinion it's better to coding with the separation of behavior about the functional domain (example: you wait for an object of kind A but you receive an object of kind B) and behavior of low-level domain (example: the unavailability of memory).
In your example, I would modify code as :
public Object getObject(){
Object objectReturned=new Object();
try{
/**business logic*/
}
catch(Exception e){
//logging and eventual logic leaving the current ojbect (this) in a consistent state
}
return objectReturned;
}
The disadvantage is to create a complete Object in every call of getObject() (then in situation where the object returned is not read or write).
But I prefer to have same object useless than a NullPointerException because sometimes this exception is very hard to fix.
Some thoughts on how to handle Exceptions
Whether returning null would be good or bad design depends on the Exception and where this snippet is placed in your system.
If the Exception is a NullPointerException you probably apply the catch block somewhat obtrusive (as flow control).
If it is something like IOException and you can't do anything against the reason, you should throw the Exception to the controller.
If the controller is a facade of a component he, translate the Exception to well documented component-specific set of possible Exceptions, that may occur at the interface. And for detailed information you should include the original Exception as nested Exception.

How can I handle StackOverflowError in Java? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
How can I handle StackOverflowError in Java?
I'm not sure what you mean with "handle".
You can certainly catch that error:
public class Example {
public static void endless() {
endless();
}
public static void main(String args[]) {
try {
endless();
} catch(StackOverflowError t) {
// more general: catch(Error t)
// anything: catch(Throwable t)
System.out.println("Caught "+t);
t.printStackTrace();
}
System.out.println("After the error...");
}
}
but that is most likely a bad idea, unless you know exactly what you are doing.
You probably have some infinite recursion going on.
I.e. a method that calls itself over and over
public void sillyMethod()
{
sillyMethod();
}
One to handle this is to fix your code so that the recursion terminates instead of continuing forever.
Take a look at Raymond Chen's post When debugging a stack overflow, you want to focus on the repeating recursive part. An extract:
If you go hunting through your defect tracking database trying to see whether this is a known issue or not, a search for the top functions on the stack is unlikely to find anything interesting. That's because stack overflows tend to happen at a random point in the recursion; each stack overflow looks superficially different from every other one even if they are the same stack overflow.
Suppose you're singing the song Frère Jacques, except that you sing each verse a few tones higher than the previous one. Eventually, you will reach the top of your singing range, and precisely where that happens depends on where your vocal limit lines up against the melody. In the melody, the first three notes are each a new "record high" (i.e., the notes are higher than any other note sung so far), and new record highs appear in the three notes of the third measure, and a final record high in the second note of the fifth measure.
If the melody represented a program's stack usage, a stack overflow could possibly occur at any of those five locations in the program's execution. In other words, the same underlying runaway recursion (musically represented by an ever-higher rendition of the melody) can manifest itself in five different ways. The "recursion" in this analogy was rather quick, just eight bars before the loop repeated. In real life, the loop can be quite long, leading to dozens of potential points where the stack overflow can manifest itself.
If you are faced with a stack overflow, then, you want to ignore the top of the stack, since that's just focusing on the specific note that exceeded your vocal range. You really want to find the entire melody, since that's what's common to all the stack overflows with the same root cause.
You might want to see if the "-Xss" option is supported by your JVM. If so, you might want to try setting it to a value of 512k (default is 256k under 32-bit Windows and Unix) and see if that does anything (other than make you sit longer until your StackOverflowException). Note that this is a per-thread setting, so if you've got a lot of threads running you also might want to bump up your heap settings.
The correct answer is the one already given. You likely either a) have a bug in your code leading to an infinite recursion which is usually quite easy to diagnose and fix, or b) have code which can lead to very deep recursions for example recursively traversing an unbalanced binary tree. In the latter situation, you need to alter your code to not allocate the information on the stack (i.e. to not recurse) but to instead allocate it in the heap.
For example, for an unbalanced tree traversal, you could store the nodes that will need to be revisited in a Stack data structure. For an in order traversal you would loop down the left branches pushing each node as you visited it until you hit a leaf, which you would process, then pop a node off the top of the stack, process it, then restart your loop with the right child (by just setting your loop variable to the right node.) This will use a constant amount of stack by moving everything that was on the stack to the heap in the Stack data structure. Heap is typically much more plentiful than stack.
As something that is usually an extremely bad idea, but is necessary in cases where memory use is extremely constrained, you can use pointer reversal. In this technique, you encode the stack into the structure you are traversing, and by reusing the links you are traversing, you can do this with no or significantly less additional memory. Using the above example, instead of pushing nodes when we loop, we just need to remember our immediate parent, and at each iteration, we set the link we traversed to the current parent and then the current parent to the node we are leaving. When we get to a leaf, we process it, then go to our parent and then we have a conundrum. We don't know whether to correct the left branch, process this node, and continue with the right branch, or to correct the right branch and go to our parent. So we need to allocate an extra bit of information as we iterate. Typically, for low-level realizations of this technique, that bit will be stored in the pointer itself leading to no additional memory and constant memory overall. This is not an option in Java, but it may be possible to squirrel away this bit in fields used for other things. In the worst-case, this is still at least 32 or 64 times reduction in the amount of memory needed. Of course, this algorithm is extremely easy to get wrong with completely confusing results and would raise utter havoc with concurrency. So it's almost never worth the maintenance nightmare except where allocating memory is untenable. The typical example being a garbage collector where algorithms like this are common.
What I really wanted to talk about, though, is when you might want to handle the StackOverflowError. Namely to provide tail call elimination on the JVM. One approach is to use trampoline style where instead of performing a tail call you return a nullary procedure object, or if you are just returning a value you return that. [Note: this requires some means of saying a function returns either A or B. In Java, probably the lightest way to do this is to return one type normally and throw the other as an exception.] Then whenever you call a method, you need to do a while loop calling the nullary procedures (which will themselves return either a nullary procedure or a value) until you get a value. An endless loop will become a while loop that is constantly forcing procedure objects that return procedure objects. The benefits of trampoline style is that it only uses a constant factor more stack than you would use with an implementation that properly eliminated all tail calls, it uses the normal Java stack for non-tail calls, the translation simple, and it only grows the code by a (tedious) constant factor. The drawback is you allocate an object on every method call (which will immediately become garbage) and consuming these objects involves a couple of indirect calls per tail call.
The ideal thing to do would be to never allocate those nullary procedures or anything else in the first place, which is exactly what tail call elimination would accomplish. Working with what Java provides though, what we could do is run the code as normal and only make these nullary procedures when we run out of stack. Now we still allocate those useless frames, but we do so on the stack rather than the heap and deallocate them in bulk, also, our calls are normal direct Java calls. The easiest way to describe this transformation is to first rewrite all multi-call-statement methods into methods that have two call statements, i.e. fgh() { f(); g(); h(); } becomes fgh() { f(); gh(); } and gh(){ g(); h(); }. For simplicity, I'll assume all methods end in a tail call, which can be arranged by just packaging the remainder of a method into a separate method, though in practice, you'd want to handle these directly. After these transformations we have three cases, either a method has zero calls in which case there is nothing to do, or it has one (tail) call, in which case we wrap it in a try-catch block in the same we will for the tail call in the two call case. Finally, it may have two calls, a non-tail call and a tail call, in which case we apply the following transformation illustrated by example (using C#'s lambda notation which could easily be replaced with an anonymous inner class with some growth):
// top-level handler
Action tlh(Action act) {
return () => {
while(true) {
try { act(); break; } catch(Bounce e) { tlh(() => e.run())(); }
}
}
}
gh() {
try { g(); } catch(Bounce e) {
throw new Bounce(tlh(() => {
e.run();
try { h(); } catch(StackOverflowError e) {
throw new Bounce(tlh(() => h());
}
});
}
try { h(); } catch(StackOverflowError e) {
throw new Bounce(tlh(() => h()));
}
}
The main benefit here is if no exception is thrown, this is the same code as we started with just with some extra exception handlers installed. Since tail calls (the h() call) don't handle the Bounce exception, that exception will fly through them unwinding those (unnecessary) frames from the stack. The non-tail calls catch the Bounce exceptions and rethrow them with the remaining code added. This will unwind the stack all the way up to the top level, eliminating the tail call frames but remembering the non-tail call frames in the nullary procedure. When we finally execute the procedure in the Bounce exception at the top-level, we will recreate all the non-tail call frames. At this point, if we immediately run out of stack again, then, since we don't reinstall the StackOverflowError handlers, it will go uncaught as desired, since we really are out of stack. If we get a little further, a new StackOverflowError will be installed as appropriate. Furthermore, if we do make progress, but then do run out of stack again, there is no benefit re-unwinding the frames we already unwound, so we install new top-level handlers so that the stack will only be unwound up to them.
The biggest problem with this approach is that you'll probably want to call normal Java methods and you may have arbitrarily little stack space when you do, so they may have enough space to start but not finish and you can't resume them in the middle. There are at least two solutions to this. The first is to ship all such work to a separate thread which will have it's own stack. This is pretty effective and pretty easy and won't introduce any concurrency (unless you want it to.) Another option is simply to purposely unwind the stack before calling any normal Java method by simply throwing a StackOverflowError immediately before them. If it still runs out of stack space when you resume, then you were screwed to begin with.
A similar thing can be done to make continuations just-in-time too. Unfortunately, this transformation isn't really bearable to do by hand in Java, and is probably borderline for languages like C# or Scala. So, transformations like this tend to be done by languages that target the JVM and not by people.
I guess you can't - or it at least depends on the jvm you use. Stack overflow means, that you have no room to store local variables and return adresses. If your jvm does some form of compiling, you have the stackoverflow in the jvm as well and that means, you can't handle it or catch it. The jvm has to terminate.
There could be a way to create a jvm that allows for such behavior, but it would be slow.
I have not tested the behavior with the jvm, but in .net you just can't handle the stackoverflow. Even try catch won't help. Since java and .net rely on the same concept (virtual machines with jit) I suspect java would behave the same. The presence of a stackoverflow-exception in .NET suggests, there might be some vm that does enable the program to catch it, the normal does not though.
Most chances to get StackOverflowError are by using [long/infinite] recursions in a recursive functions.
You can avoid Function recursion by changing your application design to use stackable data objects. There are coding patterns to convert recursive codes to iterative code blocks. Have a look at below answeres:
way-to-go-from-recursion-to-iteration
can-every-recursion-be-converted-into-iteration
design-patterns-for-converting-recursive-algorithms-to-iterative-ones
So, you avoid memory stacking by Java for your recessive function calls, by using your own data stacks.
On some occasions, you can't catch StackOverflowError.
Whenever you try, you will encounter a new one. Because it is the Java VM. It's good to find recursive code blocks, like Andrew Bullock's said.
The stack trace should indicate the nature of the problem. There should be some obvious looping when you read the stack trace.
If it's not a bug, you need add a counter or some other mechanism to halt the recursion before the recursion goes so deep it causes a stack overflow.
An example of this might be if you're handling nested XML in a DOM model with recursive calls and the XML is nested so deep it causes a stack overflow with your nested calls (unlikely, but possible). This would have to be pretty deep nesting to cause a stack overflow though.
As mentioned by many in this thread, the common cause for this is a recursive method call that doesn't terminate. Where possible avoid the stack overflow and if you this in testing you should consider this in most cases to be a serious bug. In some cases you can configure the thread stack size in Java to be larger to handle some circumstances ( large data sets being managed in local stack storage, long recursive calls) but this will increase the overall memory footprint which can lead to issues in the number of threads available in the VM. Generally if you get this exception the thread and any local data to this thread should be considered toast and not used( ie suspect and possibly corrupt).
Simple,
Look at the stack trace that the StackOverflowError produces so you know where in your code it occurs and use it to figure out how to rewrite your code so that it doesn't call itself recursively (the likely cause of your error) so it won't happen again.
StackOverflowErrors are not something that needs to be handled via a try...catch clause but it points to a basic flaw in the logic of your code that needs to be fixed by you.
java.lang.Error javadoc:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur.
So, don't. Try to find what's wrong in the logic of your code. This exception ocurrs very often because of infinite recursion.
StackOverFlow error - when you create a method in Java at the time some size of memory will be allocated in the stack memory. If you create a method inside the infinite loop then a memory allocation will be created 'n' times. When the limit for memory allocation is exceeded then the error will occur. The error is called a StackOverFlow error.
If you want to avoid this error please consider the stack memory size during the implementation from the beginning.
/*
Using Throwable we can trap any know error in JAVA..
*/
public class TestRecur {
private int i = 0;
public static void main(String[] args) {
try {
new TestRecur().show();
} catch (Throwable err) {
System.err.println("Error...");
}
}
private void show() {
System.out.println("I = " + i++);
show();
}
}
However you may have a look at the link: http://marxsoftware.blogspot.in/2009/07/diagnosing-and-resolving.html to understand the code snippet, which may raise error

Categories