OutOfMemoryError: GC Overhead Limit Exceeded – 出现内存不足的错误。超过了GC的开销限制

最后修改: 2017年 9月 4日

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 java.lang.OutOfMemoryError family, and it’s an indication of a resource (memory) exhaustion.

GC Overhead Limit Exceeded错误是来自java.lang.OutOfMemoryError家族的一个错误,它是资源(内存)耗尽的一个指示。

In this quick tutorial, we’ll look at what causes the java.lang.OutOfMemoryError: GC Overhead Limit Exceeded error and how it can be solved.

在这个快速教程中,我们将了解导致java.lang.OutOfMemoryError:GC Overhead Limit Exceeded错误以及如何解决这个问题。

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 therefore 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.

让我们看看一段抛出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 100 MB 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, check out Oracle’s Java Garbage Collection Basics tutorial.

当这个方法被调用时,JVM参数为-Xmx100m -XX:+UseParallelGC (Java堆大小被设置为100MB,GC算法为ParallelGC),我们得到一个java.lang.OutOfMemoryError。GC Overhead Limit Exceeded错误。要更好地了解不同的垃圾收集算法,请查看Oracle的Java垃圾收集基础知识教程。

We’ll get a java.lang.OutOfMemoryError: GC Overhead Limit Exceeded error very quickly by running the following command from the root of the project:

我们会得到一个java.lang.OutOfMemoryError。从项目的根部运行以下命令,很快就会得到java.lang.OutOfMemoryError: GC Overhead Limit Exceeded 的错误。

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.

还应该注意的是,在某些情况下,我们可能会在遇到GC Overhead Limit Exceeded错误之前遇到堆空间错误。

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.


These 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 1 GB 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. So, it is more advisable to thoroughly reassess the memory usage of the application.


5. Conclusion


In this article, we examined the java.lang.OutOfMemoryError: GC Overhead Limit Exceeded and the reasons behind it.

在这篇文章中,我们研究了java.lang.OutOfMemoryError:GC Overhead Limit Exceeded以及其背后的原因。

As always, the source code related to this article can be found over on GitHub.