Different Types of OutOfMemoryError You Can Encounter in Your Java Application

Java applications throw “OutOfMemoryError” when the java virtual machine does not have sufficient memory for creating new objects. There are different types of “OutOfMemoryError” that can occur in your java applications. In this article, let’s see the different types of Out-Of-Memory-Errors that can happen in your java application, the possible causes and some solutions.

The Different Types of Out-Of-Memory-Errors that can happen in your java application are

1) Heap memory error

2) Non-heap memory error

3) Native memory error

Heap memory error

java.lang.OutOfMemoryError: Java heap space

Heap memory is the runtime data area from which memory for all class instances and arrays is allocated. The Heap memory area expands dynamically. When a java application starts the heap size will be initialized to the default minimum size. When new objects are creates, memory will be allocated within the heap memory. If the heap memory is not sufficient for creating new objects, it will be automatically expanded by a fixed size. This process of expanding the heap will continue till the heap memory reaches the maximum default value.

The default maximum and minimum size for heap is 2MB and 64 MB. In server mode, the default sizes are 32MB and 128MB respectively (JVM can be run in server mode by specifying the –server flag).

You can set the min and max value of heap using the below flags:

-Xmssize in bytes

Sets the initial size of the Java heap.

-Xmxsize in bytes

Sets the maximum size to which the Java heap can grow.

The reasons for heap space going out of memory can be numerous. One simple reason can be that your application if big and cannot fit into the default VM heap space; in that case you can just specify higher sizes for the Xms and Xmx parameters.

Another reason can be that your application has some memory leak. In java, once memory is allocated for some objects, that memory will be freed by a process called garbage collection. The garbage collector can clean up objects only if they are not used. If you are not using any object and have a reference holding that object then that object will not be garbage collected. Diagnosing memory leaks can be tricky. You can use profiling tools like Optimize IT for diagnosing memory leaks.

Non-heap memory error

java.lang.OutOfMemoryError: PermGen space

The memory in the Virtual Machine is divided into a number of regions. One of these regions is PermGen. It's an area of memory that is used to (among other things) load class files. Unlike the heap memory space, the size of this memory region is fixed, i.e. it does not change when the VM is running. You can specify the size of this region with a commandline switch: -XX:MaxPermSize . The default is 64 Mb on the Sun VMs.

If there's a problem with garbage collecting classes and if you keep loading new classes, the VM will run out of space in that memory region, even if there's plenty of memory available on the heap. Setting the -Xmx parameter will not help: this parameter only specifies the size of the total heap and does not affect the size of the PermGen region.

The reasons for PermGen space error can be that you have loaded too many classes, in which can you can just increase the permgen space using the above flag.

It can also be that you are using many classloaders which have loaded the same classes thus duplicating the classes in memory. Such problems usually occur when redeploying web applications without restarting the application server.

Application servers such as Glassfish allow you to write an application (.ear, .war, etc) and deploy this application with other applications on this application server. Should you feel the need to make a change to your application, you can simply make the change in your source code, compile the source, and redeploy the application without affecting the other still running applications in the application server: you don't need to restart the application server. This mechanism works fine on Glassfish and other application servers (e.g. Java CAPS Integration Server).

The way that this works is that each application is loaded using its own classloader. Simply put, a classloader is a special class that loads .class files from jar files. When you undeploy the application, the classloader is discarded and it and all the classes that it loaded, should be garbage collected sooner or later.

Somehow, something may hold on to the classloader however, and prevent it from being garbage collected. And that's what's causing the java.lang.OutOfMemoryError: PermGen space exception. Such problems can be very difficult to solve. Read this blog for more details.

Native memory error

Whether it is heap space or permgen space, finally everything has to be allocated by the Operating System either in the RAM or in the Virtual Memory. What happens if the entire Virtual Memory is full? The OS may fail to allocate memory to the JVM. In this case a native memory error will be thrown like:

java.lang.OutOfMemoryError: request bytes for .

Out of swap space?

The reason can be that the virtual memory set in the OS is too low or you have many other applications running which are consuming lots of memory. In either case, you can try increasing the virtual memory. The procedure for increasing the virtual memory can vary from OS to OS.

In Windows, the VirtualMemory is allocated as a pagefile on the disk. When the virtual memory is full, windows will automatically increase the virtual memory and give a message “Windows is increasing your virtual memory, during this process; memory requests by some applications may be denied”.

Increasing the virtual/swap memory in unix/linux flavor operating systems can be difficult because in these operating systems, the virtual memory is allocated on a separate partition called swap partition. You will need to provide an additional swap partition or resize the existing swap partition.

There are also some special cases then Out-Of-Memory may be thrown. For example the toArray method in Collection cannot convert from the collection to array if the number of elements is more than Integer.MAX_VALUE. In that case you will get

java.lang.OutOfMemoryError: Required array size too large