JVM behavior on memory error? List s = new ArrayList <String> ();
Here is a simpler code that better shows what is happening:
try { int[] a = new int[Integer.MAX_VALUE]; } catch( Exception e ) { e.printStackTrace(); }
Array allocation fails, but that does not mean that Java no longer has free memory. If you add items to the list, the list grows in leaps. At one time, this list will require more than half the memory of the virtual machine (by default, about 64 MB). The next add will try to allocate an array that is too large.
But this means that the VM still has about 30 MB of unused heap for other tasks.
If you want to get VMs in trouble, use LinkedList
because it grows linearly. When the last allocation fails, there will be very little memory to handle the exception:
LinkedList<Integer> list = new LinkedList<Integer>(); try { for(;;) { list.add(0); } } catch( Exception e ) { e.printStackTrace(); }
This program takes longer to complete, but it still ends with an error. Java may be putting aside part of the heap for error handling or error handling, you do not need to allocate memory (allocation occurs before the code is executed).
Presumably, calling System.out.println
requires less memory than calling s.add("Pradeep")
.
If s
is an ArrayList
, for example, calling s.add
may cause the list to try to double its capacity. This is probably quite random access memory, so itโs not surprising that the JVM can continue to execute, even if it cannot perform such a relatively expensive task.
In the try block, jvm runs out of memory, while jvm exclusion is finally locked when it has no memory?
The JVM "runs out of memory" and throws OOME when an attempt to allocate an object or array fails because there is not enough space for this object. This does not mean that everything should stop immediately:
The JVM can happily continue to do things that are not related to the creation of any new objects. I am pretty sure that this is what happens in this case. (A string literal already exists, and the implementation of the
println
method most likely copies the characters to theBuffer
that was previously allocated.)The JVM can potentially allocate objects that are smaller than the one that called OOME.
Distribution of OOME may cause variables that contain references to objects to disappear from the scope, and the objects to which they refer may become inaccessible. Subsequent
new
can then initiate a GC that restores the specified objects, creating space for new ones.
Note. JLS does not indicate that the String object that this literal represents should be created when the class is loaded. However, he certainly says that it can be created during class loading ... and this is what happens in any suitable JVM.
Another answer said:
It is possible that Java allocates part of the heap for error handling or error handling, there is no need to allocate memory (allocation occurs before the code is executed).
I think that is correct. However, I think this special heap area is only used when creating an OOME instance and populating the stack trace information. Once this has happened, the JVM returns to using the regular heap. (It would be easy to get some evidence for this. Just repeat the add
call in the finally
block. If it succeeds, it indicates that something has made more memory available for general use.)
Finally, it is almost always done. When the exception was thrown, the JVM collected as much memory as possible, which, while reading your code, probably meant that it had collected a whole collection of s
.
When finally achieved, he only needs to create a new line "In finally" in the row pool , there is no additional memory, and it has no problems, since it freed up space before.
Try typing s.size()
at the end, you will see how it cannot do this. (EDIT: if in catch, finally or after the try block, there is a line of code that uses the s
collection, the garbage collector cannot collect it at the time of OOME dump. That's why the heap memory will be almost full, so any new distribution of objects can throw again one OOME. Itโs hard to predict without seeing the full code).
The JVM is not really out of memory and cannot continue. This error indicates that she was unable to allocate memory, and this is not so. This may mean that it is very low. But here it was not possible to resize the collection array, which is huge. There is not much memory left to double a large array. So it can end perfectly.
The error occurs when the heap space exceeds the value set by the -Xmx flag, and it cannot continue as usual. The error propagates, but this does not immediately lead to the JVM shutting down (from the system that exits in such cases, there would be no sense in the OOM error, since it can never be selected).
When the JVM does not exit, it will attempt, as in accordance with the language specification, to execute the finally block.