Java Out of Memory error

java.lang

Class OutOfMemoryError

 

  • All Implemented Interfaces:

 

Serializable

public class OutOfMemoryError

extends VirtualMachineError

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector. OutOfMemoryError  objects may be constructed by the virtual machine as ifsuppression were disabled and/or the stack trace was not writable .

Since:

JDK1.0

See Also:

Serialized Form

 

2 solution of java.lang.OutOfMemoryError in Java

Every one in java development face java.lang.OutOfMemoryError now and then, OutOfMemoryError in Java is one problem which is more due to system’s limitation (memory) rather than due to programming mistakes in most cases though in certain cases you could have memory leak which causing OutOfMemoryError . I have found that even though java.lang.OutOfMemoryError is quite common basic knowledge of its cause and solution is largely unknown among junior developers. In this article we will explore what is java.lang.OutOfMemoryError; Why OutOfMemoryError comes in Java application, different type of OutOfMemoryError and How to fix OutOfMemoryError in Java. This article is purely meant to provide basic knowledge of java.lang.OutMemoryError and won’t discuss profiling in detail.

What is java.lang.OutOfMemoryError in Java

OutOfMemoryError in Java is a subclass of java.lang.VirtualMachineError  and JVM throws java.lang.OutOfMemoryError when it ran out of memory in heap. OutOfMemoryError in Java can come any time in heap mostly while you try to create an object and there is not enough space in heap to allocate that object. javavdoc of OutOfMemoryError is not very informative about this though.

Types of OutOfMemoryError in Java

I have seen mainly two types of OutOfMemoryError in Java:

1) Java.lang.OutOfMemoryError: Java heap space
2) Java.lang.OutOfMemoryError: PermGen space

Though both of them occur because JVM ran out of memory they are quite different to each other and there solutions are independent to each other.

Difference between “java.lang.OutOfMemoryError: Java heap space” and “java.lang.OutOfMemoryError: PermGen space”

If you are familiar with different generations on heap and How garbage collection works in java and aware of new, old and permanent generation of heap space then you would have easily figured out this OutOfMemoryError in Java. Permanent generation of heap is used to store String pool and various Meta data required by JVM related to Class, method and other java primitives. Since in most of JVM default size of Perm Space is around “64MB” you can easily ran out of memory if you have too many classes or huge number of Strings in your project. Important point to remember is that it doesn’t depends on –Xmx value so no matter how big your total heap size you can ran OutOfMemory in perm space. Good think is you can specify size of permanent generationusing JVM options “-XX:PermSize”  and  “-XX:MaxPermSize” based on your project need.

One small thing to remember is that “=” is used to separate parameter and value while specifying size of perm space in heap while “=” is not required while  setting maximum heap size in java, as shown in below example.

export JVM_ARGS=”-Xmx1024m -XX:MaxPermSize=256m”

Another reason of “java.lang.OutOfMemoryError: PermGen ” is memory leak through Classloaders and it’s very often surfaced in WebServer and application server like tomcat, webshere, glassfish or weblogic. In Application server different classloaders are used to load different web application so that you can deploy and undeploy one application without affecting other application on same server, but while undeploying if container some how keeps reference of any class loaded by application class loader than that class and all other related class will not be garbage collected and can quickly fill the PermGen space if you deploy and undeploy your application many times. “java.lang.OutOfMemoryError: PermGen” has been observed many times in tomcat in our last project but solution of this problem are really tricky because first you need to know which class is causing memory leak and then you need to fix that. Another reason of OutOfMemoryError in PermGen space is if any thread started by application doesn’t exit when you undeploy your application.

These are just some example of infamous classloader leaks, anybody who is writing code for loading and unloading classes have to be very careful to avoid this. You can also use visualgc  for monitoring PermGen space, this tool will show graph of PermGen space and you can see how and when Permanent space getting increased. I suggest using this tool before reaching to any conclusion.

Another rather unknown but interesting cause of “java.lang.OutOfMemoryError: PermGen” we found is introduction of JVM options “-Xnoclassgc“. This option sometime used to avoid loading and unloading of classes when there is no further live references of it just to avoid performance hit due to frequent loading and unloading, but using this option is J2EE environment can be very dangerous because many framework e.g. Struts, spring etc uses reflection to create classes and with frequent deployment and undeployment you can easily ran out of space in PermGen  if earlier references was not cleaned up. This instance also points out that some time bad JVM arguments or configuration can cause OutOfMemoryError in Java.

So conclusion is avoid using “-Xnoclassgc  in J2EE environment especially with AppServer.

Tomcat to Solve OutOfMemoryError in PermGen Space

From tomcat > 6.0 onward tomcat provides memory leak detection feature which can detect many common memory leaks on web-app perspective e.g ThreadLocal memory leaks, JDBC driver registration, RMI targes, LogFactory and Thread spawned by web-apps. You can check complete details on htp://wiki.apache.org/tomcat/MemoryLeakProtection you can also detect memory leak by accessing manager application which comes with tomcat, in case you are experiencing memory leak on any java web-app its good idea to run it on tomcat.

How to solve java.lang.OutOfMemoryError: Java heap space
1) Easy way to solve OutOfMemoryError in java is to  increase the maximum heap size by using JVM options “-Xmx512M”, this will immediately solve your OutOfMemoryError. This is my preferred solution when I get OutOfMemoryError in Eclipse, Maven or ANT while building project because based upon size of project you can easily ran out of Memory.here is an example of increasing maximum heap size of JVM, Also its better to keep -Xmx to -Xms ration either 1:1 or 1:1.5 if you are setting heap size in your java application

export JVM_ARGS=”-Xms1024m -Xmx1024m”

2) Second way to resolve OutOfMemoryError in Java is rather hard and  comes when you don’t have much memory and even after increase maximum heap size you are still getting java.lang.OutOfMemoryError, in this case you probably want to profile your application and look for any memory leak. You can use Eclipse Memory Analyzer to examine your heap dump or you can use any profiler like Netbeans or JProbe. This is tough solution and requires some time to analyze and find memory leaks.

How to solve java.lang.OutOfMemoryError: PermGen space

As explained in above paragraph this OutOfMemory error in java comes when Permanent generation of heap filled up. To fix this OutOfMemoryError in Java you need to increase heap size of Perm space by using JVM option   “-XX:MaxPermSize”.  You can also specify initial size of Perm space by using    “-XX:PermSize” and keeping both initial  and maximum Perm Space you can prevent some full garbage collection which may occur when Perm Space gets re-sized. Here is how you can specify initial and maximu Perm size in Java:

export JVM_ARGS=”-XX:PermSize=64M -XX:MaxPermSize=256m”

Some time java.lang.OutOfMemoryError   in Java gets tricky and on those cases profiling remain ultimate solution.Though you have freedom to increase heap size in java, it’s recommended that to follow memory management practices while coding and setting null to any unused references.
That’s all from me on OutOfMemoryError in Java I will try to write more about finding memory leak in java and using profiler in some other post. Please share what is your approach to solve java.lang.OutOfMemoryError in Java.

Important Note: From Tomcat > 6.0 onward tomcat provides memory leak detection feature which can detect many common memory leaks on Java application e.g ThreadLocal memory leaks, JDBC driver registration, RMI targes, LogFactory and Thread spawned by webapps. You can check complete details on htp://wiki.apache.org/tomcat/MemoryLeakProtection. You can also detect memoy leak by accessing manager application which comes with tomcat, in case you are experiencing memory leak on any java webapp its good idea to run it on tomcat to find out reason of OutOfMemoryError in PermGen space.

Tools to investigate and fix OutOfMemoryError in Java

Java.lang.OutOfMemoryError is a kind of error which needs lot of investigation to find out root cause of problem, which object is taking memory, how much memory it is taking or finding dreaded memory leak and you can’t do this without having knowledge of available tools in java space. Here I am listing out some free tools which can be used to analyze heap and will help you to find culprit of OutOfMemoryError

1) Visualgc

Visualgc stands for Visual Garbage Collection Monitoring Tool and you can attach it to your instrumented hostspot JVM. Main strength of visualgc is that it displays all key data graphically including class loader, garbage collection and JVM compiler performance data.

The target JVM is identified by its virtual machine identifier also called as vmid. You can read more about visualgc and vmid options here.

2) Jmap

Jmap is a command line utility comes with JDK6 and allows you to take a memory dump of heap in a file. It’s easy to use as shwon below:

jmap -dump:format=b,file=heapdump 6054

Here file specifies name of memory dump file which is “heapdump” and 6054 is PID of your Java progress. You can find the PDI by using “ps -ef” or windows task manager or by using tool called “jps”(Java Virtual Machine Process Status Tool).

3) Jhat

Jhat was earlier known as hat (heap analyzer tool) but it is now part of JDK6. You can use jhat to analyze heap dump file created by using “jmap“. Jhat is also a command line utility and you can rum it from cmd window as shown below:

jhat -J-Xmx256m heapdump

Here it will analyze memory-dump contained in file “heapdump”. When you start jhat it will read this heap dump file and then start listening on http port, just point your browser into port where jhat is listening by default 7000 and then you can start analyzing objects present in heap dump.

4) Eclipse memory analyzer

Eclipse memory analyzer (MAT) is a tool from eclipse foundation to analyze java heap dump. It helps to find classloader leaks and memory leaks and helps to minimize memory consumption.you can use MAT to analyze heap dump carrying millions of object and it also helps you to extract suspect of memory leak. See here for more information.

Here are some of my other post on Java you may find interesting:

How Hash Map works in Java?

Difference between ClassNotFoundException and NoClassDefFoundError

Difference between String, StringBuffer and StringBuilder in Java

Difference between Comparator and Comparable with Example

10 example of enum in java

What is polymorphism in Java? Method overloading or overriding

Top 20 core java interview question and answers asked in Investment Banks

How to solve java.lang.unsupportedClassVersionError in Java

3 ways to solve java.lang.NoClassDefFoundError in Java

How to solve java.lang.ClassNotFoundException in Java

Read more: http://javarevisited.blogspot.com/2011/09/javalangoutofmemoryerror-permgen-space.html#ixzz3jp1sQVin

java.lang.OutOfMemoryError – How to solve OutOfMemoryError

In this example we will discuss about OutOfMemoryError in Java. This error is thrown by the Java Virtual Machine (JVM) when an object cannot be allocated due to lack of memory space and also, the garbage collector cannot free some space. The OutOfMemoryError objects are created by the JVM when suppression is disabled and/ir the stack trace is not writable.

The OutOfMemoryError extends the VirtualMachineError class, which indicates that the JVM is broken, or it has run out of resources and cannot operate. Furthermore, the the VirtualMachineError extends the  Errorclass, which is used to indicate those serious problems that an application should not catch. A method may not declare such errors in its throwclause, because these errors are abnormal conditions that shall never occur.

Finally, the OutOfMemoryError exists since the 1.0 version of Java.

The Structure of OutOfMemoryError

Constructors

  • OutOfMemoryError()

Creates an instance of the OutOfMemoryError class, setting null  as its message.

  • OutOfMemoryError(String s)

Creates an instance of the OutOfMemoryError class, using the specified string as message. The string argument indicates the name of the class that threw the error.

The OutOfMemoryError in Java

As we have already explained, the OutOfMemoryError indicates that a new object cannot be created, due to lack of available memory space. The following example reproduces this case:

OutOfMemmoryExample.java:

public class OutOfMemoryErrorExample {

public static void main(String[] args) {

Long maxMemory = Runtime.getRuntime().maxMemory();

System.out.println(maxMemory);

 

int[] matrix = new int[(int) (maxMemory + 1)];

for(int i = 0; i < matrix.length; ++i)

matrix[i] = i+1;

}

}

In this example, we retrieve and print the available free memory inside the Java Virtual Machine (JVM), using the methodfreeMemory from the Runtime class. Then, we attempt to create a matrix of integers, whose size is bigger than the available free memory and thus, an OutOfMemoryError is thrown.

A sample execution is shown below:

1841823744

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

at main.java.OutOfMemoryErrorExample.main(OutOfMemoryErrorExample.java:8)

The java.lang.OutOfMemoryError: Java heap space error is thrown because we tried to allocate, more than the available, memory space. Each Java application can use only a limited amount of memory. This amount is specified at the startup of the JVM, by the following parameters:

  • -Xms <size> : specifies the minimum Java heap size.
  • -Xmx <size> : specifies the minimum Java heap size.

You can find the default values for many parameters of the JVM, by issuing the following command in a Linux or Mac terminal:

$ java -XX:+PrintFlagsFinal -version | grep -iE ‘HeapSize|PermSize|ThreadStackSize’

intx CompilerThreadStackSize                   = 0               {pd product}

uintx ErgoHeapSizeLimit                         = 0               {product}

uintx HeapSizePerGCThread                       = 87241520        {product}

uintx InitialHeapSize                          := 130023424       {product}

uintx LargePageHeapSizeThreshold                = 134217728       {product}

uintx MaxHeapSize                              := 2071986176      {product}

intx ThreadStackSize                           = 1024            {pd product}

intx VMThreadStackSize                         = 1024            {pd product}

java version “1.8.0_11”

Java(TM) SE Runtime Environment (build 1.8.0_11-b12)

Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode)

In Windows, you may use the following command:

java -XX:+PrintFlagsFinal -version | findstr /i “HeapSize PermSize ThreadStackSize”

For a complete list of all the parameters of the JVM, you shall execute the following command:

java -XX:+PrintFlagsFinal -version

More about the OutOfMemoryError in Java

The OutOfMemoryError is thrown due to lack of available memory space. The garbage collector is responsible for detecting objects that are not being used or referenced and collect them. In this way, memory space is being reclaimed for Java applications. However, there are cases where the garbage collector cannot reclaim portions of memory, despite the fact that these objects are no longer accessible by the Java application. These are called memory leaks  and can severely limitate the available memory space.

Memory leaks can be created very easily in Java:

MemoryLeakExample.java:

import java.util.HashMap;

import java.util.Map;

import java.util.Random;

public class MemoryLeakExample {

public static void main(String[] args) {

Random random = new Random();

Map sampleMap = new HashMap();

 

// Loop forever…

while(true) {

// Create and store a random pair.

int randomValue = random.nextInt();

sampleMap.put(randomValue, String.valueOf(randomValue));

}

}

}

In this example, we create and store random pairs in a  HashMap. However, our application only stores values to theHashMap and never retrieves values from it. Thus, memory space is occupied for no reason and the garbage collector cannot reclaim that space, because our application holds a reference to that HashMap. Thus, memory leaks are essential for memory space and must be removed.

Finally, as you can see from here, there are many different causes that can throw an OutOfMemoryError in Java:

  • java.lang.OutOfMemoryError:  Java heap space.
  • java.lang.OutOfMemoryError:  PermGen space.

This error indicates that the permanent generation is full. In Java, the permanent generation is the memory space where class and method objects are stored.

  • java.lang.OutOfMemoryError:  Requested array size exceeds VM limit.

This error indicates that a Java application attempts ti allocate an array, whose size is larger than the heap size. For example:

public class OutOfMemoryErrorVMLimitExample {

public static void main(String[] args) {

int[] matrix = new int[Integer.MAX_VALUE];

 

for(int i = 0; i < matrix.length; ++i)

matrix[i] = i+1;

}

}

 

A sample execution is shown below:

Exception in thread “main” java.lang.OutOfMemoryError: Requested array size exceeds VM limit

at main.java.OutOfMemoryErrorVMLimitExample.main(OutOfMemoryErrorVMLimitExample.java:5)

 

  • java.lang.OutOfMemoryError:  request <size> bytes for <reason>. Out of swap space?

This error indicates that an allocation from the native heap space has failed and also, the heap space is close to exhaustion. Moreover, the message of the error indicates the number of bytes that failed and the reason for the memory request.

  • java.lang.OutOfMemoryError:  <reason> <stack trace> (Native method).

This error indicates that the allocation failure was detected in a JNI or native method instead of the JVM code.

How to deal with the OutOfMemoryError

  • The most obvious solution to this error is to increase the available memory size for the Java Virtual Machine. If your application requires more memory then, you shall grant it to your application.
  • Verify that your application does not store unnecessary information. Store and maintain only those pieces of information required for the proper execution of your Java application.
  • You can use the availabe memory analyzer tools, in order to carefully observe the portions of memory occupied by your application. Examples of such tools are the Eclipse Memory Analyzer and  Java Heap Analysis Tool (jhat).

Download the Eclipse Project

This was a tutorial about OutOfMemoryError in Java.

Download
You can download the full source code of this example here: OutOfMemoryErrorExamples.zip.

 

java.lang.OutOfMemoryError:Java heap space

Java applications are only allowed to use a limited amount of memory. This limit is specified during application startup. To make things more complex, Java memory is separated into two different regions. These regions are called Heap space and Permgen (for Permanent Generation):

The size of those regions is set during the Java Virtual Machine (JVM) launch and can be customized by specifying JVM parameters -Xmx  and -XX:MaxPermSize. If you do not explicitly set the sizes, platform-specific defaults will be used.

The java.lang.OutOfMemoryError: Java heap space error will be triggered when the application attempts to add more data into the heap space area, but there is not enough room for it.

Note that there might be plenty of physical memory available, but thejava.lang.OutOfMemoryError: Java heap space  error is thrown whenever the JVM reaches the heap size limit.

The cause

There most common reason for the java.lang.OutOfMemoryError: Java heap space error is simple – you try to fit an XXL application into an S-sized Java heap space. That is – the application just requires more Java heap space than available to it to operate normally. Other causes for this OutOfMemoryError message are more complex and are caused by a programming error:

  • Spikes in usage/data volume. The application was designed to handle a certain amount of users or a certain amount of data. When the number of users or the volume of data suddenly spikes and crosses that expected threshold, the operation which functioned normally before the spike ceases to operate and triggers the java.lang.OutOfMemoryError: Java heap space error.
  • Memory leaks. A particular type of programming error will lead your application to constantly consume more memory. Every time the leaking functionality of the application is used it leaves some objects behind into the Java heap space. Over time the leaked objects consume all of the available Java heap space and trigger the already familiar java.lang.OutOfMemoryError: Java heap space error.

Solution to the problem Automatic root cause detection of OutOfMemoryErrors TRY PLUMBR

Examples

Trivial example

The first example is truly simple – the following Java code tries to allocate an array of 2M integers. When you compile it and launch with 12MB of Java heap space (java -Xmx12m OOM), it fails with the java.lang.OutOfMemoryError: Java heap space  message. With 13MB Java heap space the program runs just fine.

class OOM {

static final int SIZE=2*1024*1024;

public static void main(String[] a) {

int[] i = new int[SIZE];

}

}

Memory leak example

The second and a more realistic example is of a memory leak. In Java, when developers create and use new objects e.g. new Integer(5) , they don’t have to allocate memory themselves – this is being taken care of by the Java Virtual Machine (JVM). During the life of the application the JVM periodically checks which objects in memory are still being used and which are not. Unused objects can be discarded and the memory reclaimed and reused again. This process is called Garbage Collection. The corresponding module in JVM taking care of the collection is called the Garbage Collector (GC).

Java’s automatic memory management relies on GC to periodically look for unused objects and remove them. Simplifying a bit we can say that a memory leak in Java is a situation where some objects are no longer used by the application but Garbage Collection fails to recognize it. As a result these unused objects remain in Java heap space indefinitely. This pileup will eventually trigger the java.lang.OutOfMemoryError: Java heap space  error.

It is fairly easy to construct a Java program that satisfies the definition of a memory leak:

class KeylessEntry {

 

static class Key {

Integer id;

 

Key(Integer id) {

this.id = id;

}

 

@Override

public int hashCode() {

return id.hashCode();

}

}

 

public static void main(String[] args) {

Map m = new HashMap();

while (true)

for (int i = 0; i < 10000; i++)

if (!m.containsKey(new Key(i)))

m.put(new Key(i), “Number:” + i);

}

}

When you execute the above code above you might expect it to run forever without any problems, assuming that the naive caching solution only expands the underlying Map to 10,000 elements, as beyond that all the keys will already be present in the HashMap. However, in reality the elements will keep being added as the Key class does not contain a proper equals() implementation next to its hashCode().

As a result, over time, with the leaking code constantly used, the “cached” results end up consuming a lot of Java heap space. And when the leaked memory fills all of the available memory in the heap region and Garbage Collection is not able to clean it, thejava.lang.OutOfMemoryError:Java heap space  is thrown.

The solution would be easy – add the implementation for the  equals() method similar to the one below and you will be good to go. But before you manage to find the cause, you will definitely have lose some precious brain cells.

@Override

public boolean equals(Object o) {

boolean response = false;

if (o instanceof Key) {

response = (((Key)o).id).equals(this.id);

}

return response;

}

Solution to the problem No OutOfMemoryError goes unnoticedGET AUTOMATIC ROOT CAUSE DETECTION

The solution

The first solution should be obvious – when your JVM runs out of a particular resource, you should increase the availability of that resource. In our case: when your application does not have enough Java heap space memory to run properly, fixing it is as easy as altering your JVM launch configuration and adding (or increasing if present) the following:

-Xmx1024m

The above configuration would give the application 1024MB of Java heap space. You can use g or G for GB, m or M for MB, k or K for KB. For example all of the following are equivalent to saying that the maximum Java heap space is 1GB:

java -Xmx1073741824 com.mycompany.MyClass

java -Xmx1048576k com.mycompany.MyClass

java -Xmx1024m com.mycompany.MyClass

java -Xmx1g com.mycompany.MyClass

In many cases however, providing more Java heap space is not exactly going to solve the problem. For example, if your application contains a memory leak, adding more heap will just postpone the java.lang.OutOfMemoryError: Java heap space  error. Additionally, increasing the amount of Java heap space also tends to increase the length of GC pauses affecting your application’s throughput or latency.

If you wish to solve the underlying problem with the Java heap space instead of masking the symptoms, you have several tools at your disposal. Debuggers, profilers, heap dump analyzers – the choice is yours. For an automated solution we suggest Plumbr, the Java monitoring solution with root cause detection. Among other performance problems it catches all java.lang.OutOfMemoryErrors and automatically tells you what causes them. A free 14-day trial account includes full root cause detection functionality.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s