2

I'm working on a simple application and now I'm not quite sure how to deal with errors occured while executing application. I'm particularly worried about OutOfMemoryError. Example:

    try{
        while(true){
            //do some job
        }
    } catch (Exception e){
        System.out.println("Exception occured");
    } catch (Throwable t){
        //log entry of abnormal termination
        System.exit(1);
    } finally {
        //Terminate application normally
    }

Is it a correct way to deal with such situation? I mean to attempt to terminate application normally in finally block and just kill JVM in catch(Throwable t).

The issue is finally will never be executed if, say, OutOfMemoryError was thrown.

Alupkers
  • 223
  • 1
  • 9

3 Answers3

3

I don't think that's even needed, if you want to kill your JVM on OutOfMemoryException, you can include some JVM flags:

-XX:OnOutOfMemoryError="kill -9 %p"

It may be possible to free up some memory when hitting OutOfMemoryException depending on what you're doing and it's probably better to explicitly try and catch OutOfMemoryException rather than catching Throwable which includes everything that can be thrown.

Jan Vladimir Mostert
  • 12,380
  • 15
  • 80
  • 137
1

If it is a single threaded application, you could just log the OOM, and let the VM finish normally, don't invoke the System.exit(). If it is multi-threaded application, you need to have a policy of shutting it down. In every scenario it is up to you which resources and how should be handled when you need to shutdown your application. You are worried about finally not invoking after System.exit(), if you have more threads they will be killed and you have no control when, they also wouldn't have chance for any finaliztion. If you would like to shutdown your app gracefully then you need to program it in such way to have the logic that does this.

Krzysztof Cichocki
  • 6,294
  • 1
  • 16
  • 32
  • Aren't all resources reclaimed when we call `System.exit(1)`? – Alupkers May 29 '16 at 14:52
  • 1
    They are in a scope that is possible for OS and JVM - but there can be exceptions eg. applications that are using native code. But, it is not the point of my answer that some native resources will not come back to OS, but if your threads are doing something transactional - eg. writing some "atomic" chunks of data to the file on hard drive, then if you kill the VM, there is big chance that your file is in inconsistent state, because there will be some half-chunks of data in it. There are plenty of scenarios in which killing the VM could result in some inconsisten state of your application. – Krzysztof Cichocki May 29 '16 at 16:53
1

If you call System.exit(...) in a catch block for some exception then a finally block will not be executed if the exception is caught.

Assuming that is what you want to happen ... then you have coded your exception handling correctly.

Is that the "correct" way to deal with this? Well, if this is what you want to happen (i.e. if you want any Error exceptions to cause the normal termination logic to be skipped) then it is correct. But ultimately, you need to decide for yourself.

Having said that, if you are concerned that your application won't be able to perform the termination because it is out of memory, then you could do something like this:

try {
    int[] reserved = new int[1,000,000];
    while(true){
        //do some job
    }
} catch (Exception e){
    System.out.println("Exception occured");
} catch (Throwable t){
    //log entry of abnormal termination
}
// Terminate application normally << HERE

If the JVM throws OOME, when you reach the "HERE" point, there will be a 8MB of reclaimable garbage in the heap. If the termination code fills the heap (again) then the GC will reclaim that garbage and there should be enough space to complete the termination.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • What do you mean enough space to complete the termination? Does it require some heap space? – Alupkers May 29 '16 at 14:51
  • @Alupkers - What I am saying is that your "terminate application code" might need some heap space. If it doesn't then there is no issue, and no need to reserve space. – Stephen C May 29 '16 at 15:05