I'm confused on what OutOfMemoryError really is.
The question I have asks what the OutOfMemory exception signifies:
- The process ran out of heap space
- Process ran out of physical memory
- Operating system ran out of virtual memory.
I have looked around online and there are many different answers for both number 1 and 3. I'm leaning towards answer 1 but I'm not so sure.
CodePudding user response:
The most common case for OutOfMemoryError
=> It can happen when the heap is getting overrun and the (generally full GC
) GC
is running all the time to reclaim heap space but is unable make any meaningful progress. This is the most common
use case as others have also pointed out.
Process ran out of physical memory => When the process is reaching that threshold and paging is going over a certain threshold then the OS
would act and kill the process and/or other processes. It could also be that the JVM throws an OutOfMemoryError
before that happens. It might also be that the JVM
throws not one but repeatedly many OutOfMemoryErrors
. And then the OS takes over. See below for the Linux OOM Killer
.
OS ran out of virtual memory or is system configured to not use any virtual memory => the JVM process can signal a OutOfMemoryError
or the OS
can kill it as specified.
In addition to what is already answered, need to point out that in certain cases, the only evidence of the JVM
process being killed is in the OS
logs. You would not find any trace of the JVM throwing an OutOfMemoryError
at all.
Note the JVM OOM error(OutOfMemoryError
) is available on a best case basis. As there might be situations in which the JVM is unable to proceed further to even throw that error. It could also happen in case when the OS
does a "kill -9
" of processes that could include the JVM
. For more info, read on the "Linux OOM Killer" wherein the memory requirements exceed a certain threshold in the system.
CodePudding user response:
The answer is: potentially all of them, more or less.
If you fill up the regular Java heap (and the GC is unable to reclaim enough space) you will get an OutOfMemoryError
. This is the most common case.
A process does not run out of physical memory per se. Physical memory is the operating system's concern. A process only sees virtual memory.
However, there are a few cases where you can get failures related to running out of physical RAM or virtual memory address space. For example:
- When a 32-bit process fills all of the 32 bit address space (or at least all of it that can be mapped by the OS).
- When a process runs against virtual address space limits set from the outside; e.g. using
ulimit
on Linux. - When the OS runs out of swap space for new virtual memory allocations.
- When swapping is disabled, and the OS runs out of physical RAM.
Each of these scenarios ... and others ... can trigger unusual OutOfMemoryError
s at the point where the JVM requests a memory-related resource from the OS; e.g. to create a thread stack, allocate a direct buffer, grow the heap, and so on.
You can typically distinguish the different causes by looking carefully at the exception messages. But doing it programmatically would be awkward.
And there is another scenario. If the operating system has overcommitted RAM, and it notices that the virtual memory system is doing excessive paging / swapping I/O, the OSes "oomkiller" may decide to kill a process. If the "victim" is a JVM, the Java application won't get an OutOfMemoryError
at all, and it won't even get to execute shutdown hooks. It will be "kill -9"'d.