1. Overview
Simply put, the JVM takes care of freeing up memory when objects are no longer being used; this process is called Garbage Collection (GC).
The GC Overhead Limit Exceeded error is one from the family of java.lang.OutOfMemoryError and is an indication of a resource (memory) exhaustion.
In this quick article, we’ll look at what causes the java.lang.OutOfMemoryError: GC Overhead Limit Exceeded error and how it can be solved.
2. GC Overhead Limit Exceeded Error
OutOfMemoryError is a subclass of java.lang.VirtualMachineError; it’s thrown by the JVM when it encounters a problem related to utilizing resources. More specifically, the error occurs when the JVM spent too much time performing Garbage Collection and was only able to reclaim very little heap space.
According to Java docs, by default, the JVM is configured to throw this error if the Java process spends more than 98% of its time doing GC and when only less than 2% of the heap is recovered in each run. In other words, this means that our application has exhausted nearly all the available memory and the Garbage Collector has spent too much time trying to clean it and failed repeatedly.
In this situation, users experience extreme slowness of the application. Certain operations, which usually complete in milliseconds, take more time to complete. This is because the CPU is using its entire capacity for Garbage Collection and hence cannot perform any other tasks.
3. Error in Action
Let’s look at a piece of code that throws java.lang.OutOfMemoryError: GC Overhead Limit Exceeded.
We can achieve that, for example, by adding key-value pairs in an unterminated loop:
public class OutOfMemoryGCLimitExceed { public static void addRandomDataToMap() { Map<Integer, String> dataMap = new HashMap<>(); Random r = new Random(); while (true) { dataMap.put(r.nextInt(), String.valueOf(r.nextInt())); } } }
When this method is invoked, with the JVM arguments as -Xmx100m -XX:+UseParallelGC (Java heap size is set to 100MB and the GC Algorithm is ParallelGC), we get a java.lang.OutOfMemoryError: GC Overhead Limit Exceeded error. To get a better understanding of different Garbage Collection Algorithms we can check Oracle’s Java Garbage Collection Basics tutorial.
We’ll get a java.lang.OutOfMemoryError: GC Overhead Limit Exceeded error very quickly by running following command from the root of the project:
mvn exec:exec
It should also be noted that in some situations we might encounter a heap space error before encountering the GC Overhead Limit Exceeded error.
4. Solving GC Overhead Limit Exceeded Error
The ideal solution is to find the underlying problem with the application by examining the code for any memory leaks.
Following questions need to be addressed:
- What are the objects in the application that occupy large portions of the heap?
- In which parts of the source code are these objects being allocated?
We can also use automated graphical tools such as JConsole which helps to detect performance problems in the code including java.lang.OutOfMemoryErrors.
The last resort would be to increase the heap size by altering the JVM launch configuration. For example, this gives 1GB heap space for the Java application:
java -Xmx1024m com.xyz.TheClassName
However, this will not solve the problem if there are memory leaks in the actual application code. Instead, we will just postpone the error. Therefore, it is more advisable to re-assess the memory usage of the application thoroughly.
5. Conclusion
In this tutorial, we examined the java.lang.OutOfMemoryError: GC Overhead Limit Exceeded and the reasons behind it.
As always, the source code related to this article can be found over on GitHub.