Error java.lang.OutOfMemoryError: GC overhead limit exceeded

1,061,723

Solution 1

This message means that for some reason the garbage collector is taking an excessive amount of time (by default 98% of all CPU time of the process) and recovers very little memory in each run (by default 2% of the heap).

This effectively means that your program stops doing any progress and is busy running only the garbage collection at all time.

To prevent your application from soaking up CPU time without getting anything done, the JVM throws this Error so that you have a chance of diagnosing the problem.

The rare cases where I've seen this happen is where some code was creating tons of temporary objects and tons of weakly-referenced objects in an already very memory-constrained environment.

Check out the Java GC tuning guide, which is available for various Java versions and contains sections about this specific problem:

Solution 2

Quoting from Oracle's article "Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning":

Excessive GC Time and OutOfMemoryError

The parallel collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small. If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.

EDIT: looks like someone can type faster than me :)

Solution 3

If you are sure there are no memory leaks in your program, try to:

  1. Increase the heap size, for example -Xmx1g.
  2. Enable the concurrent low pause collector -XX:+UseConcMarkSweepGC.
  3. Reuse existing objects when possible to save some memory.

If necessary, the limit check can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.

Solution 4

It's usually the code. Here's a simple example:

import java.util.*;

public class GarbageCollector {

    public static void main(String... args) {

        System.out.printf("Testing...%n");
        List<Double> list = new ArrayList<Double>();
        for (int outer = 0; outer < 10000; outer++) {

            // list = new ArrayList<Double>(10000); // BAD
            // list = new ArrayList<Double>(); // WORSE
            list.clear(); // BETTER

            for (int inner = 0; inner < 10000; inner++) {
                list.add(Math.random());
            }

            if (outer % 1000 == 0) {
                System.out.printf("Outer loop at %d%n", outer);
            }

        }
        System.out.printf("Done.%n");
    }
}

Using Java 1.6.0_24-b07 on a Windows 7 32 bit.

java -Xloggc:gc.log GarbageCollector

Then look at gc.log

  • Triggered 444 times using BAD method
  • Triggered 666 times using WORSE method
  • Triggered 354 times using BETTER method

Now granted, this is not the best test or the best design but when faced with a situation where you have no choice but implementing such a loop or when dealing with existing code that behaves badly, choosing to reuse objects instead of creating new ones can reduce the number of times the garbage collector gets in the way...

Solution 5

Cause for the error according to the Java [8] Platform, Standard Edition Troubleshooting Guide: (emphasis and line breaks added)

[...] "GC overhead limit exceeded" indicates that the garbage collector is running all the time and Java program is making very slow progress.

After a garbage collection, if the Java process is spending more than approximately 98% of its time doing garbage collection and if it is recovering less than 2% of the heap and has been doing so far the last 5 (compile time constant) consecutive garbage collections, then a java.lang.OutOfMemoryError is thrown. [...]

  1. Increase the heap size if current heap is not enough.
  2. If you still get this error after increasing heap memory, use memory profiling tools like MAT ( Memory analyzer tool), Visual VM etc and fix memory leaks.
  3. Upgrade JDK version to latest version ( 1.8.x) or at least 1.7.x and use G1GC algorithm. . The throughput goal for the G1 GC is 90 percent application time and 10 percent garbage collection time
  4. Apart from setting heap memory with -Xms1g -Xmx2g , try

    -XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m  
    -XX:ParallelGCThreads=n -XX:ConcGCThreads=n
    

Have a look at some more related questions regarding G1GC

Share:
1,061,723
Mnementh
Author by

Mnementh

My name is Jörgen Kosche. I'm a programmer using mostly Java.

Updated on July 27, 2022

Comments

  • Mnementh
    Mnementh almost 2 years

    I get this error message as I execute my JUnit tests:

    java.lang.OutOfMemoryError: GC overhead limit exceeded
    

    I know what an OutOfMemoryError is, but what does GC overhead limit mean? How can I solve this?

  • Stephen C
    Stephen C almost 15 years
    "You can turn this off..." but the OP most likely should not do this.
  • Susheel Javadi
    Susheel Javadi about 14 years
    Can you tell me the difference between "-XX" and "-Xmx"? I was able to turn it off using the "-Xmx" option too.
  • Tim Cooper
    Tim Cooper about 14 years
    Would it be correct to summarise your answer as follows: "It's just like an 'Out of Java Heap space' error. Give it more memory with -Xmx." ?
  • Joachim Sauer
    Joachim Sauer about 14 years
    @Tim: No, that wouldn't be correct. While giving it more memory could reduce the problem, you should also look at your code and see why it produces that amount of garbage and why your code skims just below the "out of memory" mark. It's often a sign of broken code.
  • Joachim Sauer
    Joachim Sauer over 13 years
    Thanks, it seems Oracle isn't actually that good in data migration, they broke the link.
  • Andrzej Doyle
    Andrzej Doyle over 13 years
    Replying to a very old comment here, but... @Bart The -XX: at the start of several command line options is a flag of sorts indicating that this option is highly VM-specific and unstable (subject to change without notice in future versions). In any case, the -XX:-UseGCOverheadLimit flag tells the VM to disable GC overhead limit checking (actually "turns it off"), whereas your -Xmx command merely increased the heap. In the latter case the GC overhead checking was still running, it just sounds like a bigger heap solved the GC thrashing issues in your case (this will not always help).
  • A.W.
    A.W. over 12 years
    I am investigating the same problem in a application running on Weblogic. It runs on a server shared with other application running on Weblogic. Does the error mean it always has to do with my application therefore can rule out problems in the other applications on the same server? Or is there a possibility other applications can interfere with your environment. Just asking cause it's hard to find the cause of memory leaks.
  • Joachim Sauer
    Joachim Sauer over 12 years
    @Guus: if multiple applications run in the same JVM, then yes, they can easily influence each other. It'll be hard to tell which one is misbehaving. Separating the applications into distinct JVMs might be the easiest solution.
  • A.W.
    A.W. over 12 years
    @Joachim: server is located at a client. I checked with them and the applications do run in separate JVMs. I stress tested the app on our server and cannot get it to go out of memory. Could another process (java or non java) on the server somehow be the cause of my app to go out of memory?
  • Joachim Sauer
    Joachim Sauer over 12 years
    @Guus: no, especially not with the error message discussed here. It's more likely to be an artifact of configuration and/or specific loads that trigger the problem. But you really ought to ask this in a separate question (with as much detail as possible), it's getting too much for the comments here.
  • deniz
    deniz about 12 years
    Please clarify: When you say "Triggered n times", does that mean that a regular GC happened n times, or that the "GC overhead limit exceeded" error reported by the OP happened n times?
  • Ar5hv1r
    Ar5hv1r almost 11 years
    @TimCooper - that's honestly a poor answer even for the Out of Java Heap space error, though it's certainly sometimes necessary. To trigger this Error, however, you really have to be beating up the JVM, it's quite good at efficiently collecting garbage. If you're seeing this error, it is far more likely you're doing something violently cruel to the JVM than it is that you're simply overloading the heap.
  • onionjake
    onionjake over 10 years
    Is this specific to Java 6? Does the same issue happen in Java 7?
  • Zds
    Zds about 10 years
    @TimCooper: Just giving more memory is often quite.. blunt tool for resolving issues like this. It's often more useful to look first at if you create lot of new objects, but also if you memory is properly split. Often the problem is that one of the three areas is at upper limit, but the others have plenty of free space. Then re-partitioning the JVM memory pools would help.
  • Blaze Tama
    Blaze Tama over 9 years
    The android apps dont have arguments tab...what should we do to achieve this?
  • Hamza
    Hamza over 9 years
    the most simple way to fix this problem. Thanks :)
  • Abhinaba Basu
    Abhinaba Basu about 9 years
    eclipse.ini file in jdev?
  • reinierpost
    reinierpost over 8 years
    I'd just had this happen to me with Java 7 and a web application containing 2001670 lines of Java code, of which I wrote about 5. "You should also look at your code" is not so easy in such cases.
  • RobbZ
    RobbZ over 8 years
    In my application (reading a large Excel file in Talend) this did not work and from other users explanation I understand why. This just disables the error but the problem persists and your application will just spend most of its time handling GC. Our server had plenty of RAM so I used the suggestions by Vitalii to increase the heap size.
  • zionpi
    zionpi about 8 years
    problems unsolved even when the configuration has been changed to this.
  • Fengzmg
    Fengzmg about 8 years
    These settings are only specific to your local IDE. This will no work for Prod environment.
  • Phoenix
    Phoenix almost 8 years
    problem not yet solved. do you have / know any other way?
  • Michael Piefel
    Michael Piefel almost 8 years
    What tool is that answer for? That was not an Eclipse question.
  • Michael Piefel
    Michael Piefel almost 8 years
    The OP did not ask an Eclipse question.
  • Diego Queiroz
    Diego Queiroz over 7 years
    There is no "minimum limit". -Xms is the initial size.
  • deldev
    deldev over 7 years
    Looking for a help to my issue, I've found this stackoverflow.com/questions/110083/…. The GC would be affected whether create an object inside or out a loop?
  • Joshua Pinter
    Joshua Pinter over 7 years
    Works great for the simulator. Any idea how this affects real devices? i.e. is this a good idea or is it just masking the issue? Thanks.
  • Alex
    Alex over 7 years
    Yes, when using Gradle :)
  • JPerk
    JPerk about 7 years
    What is the max of maximum limit that could be set??
  • Freitags
    Freitags almost 7 years
    This "answer" does not answer the question above.
  • mcoolive
    mcoolive almost 7 years
    I disagree with the third advice. Reuse existing objects do not save memory (do not leak old objects save memory :-) Moreover "reuse existing object" was a practice to relieve GC pressure. But it's NOT ALWAYS a good idea: with modern GC, we should avoid situations where old objects hold new ones because it can break some locality assumptions...
  • Julian L.
    Julian L. over 5 years
    How could you even think this is a solution to his question in general? You set your heap size to 4g which is totally arbitrary in a gradle configuration for Android facepalm.
  • Pievis
    Pievis over 5 years
    You will eventually get this error if your application is data intensive, clearing the memory and evading data leak is the best way out - but requires some time.
  • Abhishek
    Abhishek over 4 years
    Before trying out any of the above things I would suggest close the android studio and kill all Java/JVM related processes(or restart your system). One of the reasons for this error is way too many Java processes are running and GC is not able to run properly. Now open your android studio and try building it again if it still doesn't work you can increase the heap size as mentioned in earlier answers.
  • Mark Stewart
    Mark Stewart over 4 years
    I tested just now using java 1.8.0_91 and never got an error/exception, and the "Triggered n times" was from counting up the number of lines in the gc.log file. My tests show much fewer times overall, but fewest "Triggers" times for BETTER, and now, BAD is "badder" than WORST now. My counts: BAD: 26, WORSE: 22, BETTER 21.
  • Mark Stewart
    Mark Stewart over 4 years
    I just added a "WORST_YET" modification where I define the List<Double> list in the outer loop instead of before the outer loop, and Triggered 39 garbage collections.
  • Mark Stewart
    Mark Stewart over 4 years
    @mcoolive: For a somewhat contrived example, see the comments to answer stackoverflow.com/a/5640498/4178262 below; creating the List object inside the loop caused GC to be called 39 times instead of 22 times.
  • Tiina
    Tiina about 4 years
    Today I study different GCs for the same code. SerialGC does not have this problem, but ParallelGC does. I don't know the reason yet.
  • PJvG
    PJvG over 3 years
    @JPerk the max is as much as the physical memory of your machine. However, other applications will compete over memory use if you try that.
  • Soheil Rahsaz
    Soheil Rahsaz almost 3 years
    @TimCooper, I had Out of Java Heap error at first , then I increased it's memory, now I'm getting GC overhead error! :D
  • Trenton Telge
    Trenton Telge over 2 years
    I ended up having to use this option for a maven build that ate up around 4G of memory. I tried increasing the heap size with -Xmx8192M, but this flag is the only thing that worked.