Is garbage collection performed after an OutOfMemoryError is thrown in java?
It certainly works up to which OOME throws. In fact, OOME is usually thrown away because the garbage collector discovers that it cannot return enough space to satisfy distribution request 1 .
Whether it is executed after the one that OOME has chosen depends on what the application does. If an application tries to continue, the GC will usually start the next time the application asks for more memory ... as it continues to run.
1 - In fact, you can configure the GC to throw OOME when it detects that it spends too much time collecting garbage. In this case, the JVM may have a useful amount of unallocated memory in the hand.
Aaron Digullah says the following:
So, in a carefully designed application, you can catch and process OOME, and the program will survive and continue to work.
This is true, but this is not something you usually should do for two reasons.
The first reason is that OOME can be thrown anywhere where the thread is trying to allocate memory. Regardless of what the JVM was doing at that time, it will be terminated ... until the moment when OOME is caught. For instance:
If the stream was in the middle of updating the general data structure (under a lock), the data structure will be left half updated.
If the thread was supposed to notify of some other thread, this notification will never happen, and the other thread will wait.
If the thread does not catch OOME, it will be terminated, and if it does not notice anything, then you will potentially remain with an application that no longer works.
The problem is that these βbreakdownsβ are difficult to detect or predict and difficult to repair.
The second reason is that OOME usually points to one of the following things:
You tried to perform a calculation with insufficient heap memory. If you try to recover from OOME, chances are you will run into the same problem again.
Your application has a memory leak; those. some data structure in your application supports references to garbage objects and prevents them from being recovered. Most likely, if you try to recover from OOME, nothing will change, and you will encounter the same problem again, and again and again.
So, the prerequisites for a successful recovery are as follows:
- to know that OOME cannot damage anything in the JVM, which is important, AND
- know that you will no longer run OOME again ... because the underlying reason still exists.
These are difficult prerequisites to satisfy ... in most applications. If they are not completed, then there is a good chance that an attempt to restore from OOME will lead to a deterioration if you exit and restart the application.