J Fabian Meier
J Fabian Meier

Reputation: 35903

GC overhead limit exceeded, but memory left

I got a

java.lang.OutOfMemoryError: GC overhead limit exceeded

while splitting some strings. Interestingly, neither the memory was used up nor the garbage collector was going crazy: JVisualVM output

The exception appeared at 11:10, when Eclipse froze the program before actually throwing the exception. So everything after 11:10 may be just noise.

I repeatedly run into this issue in my long-running program but I do not know how to avoid it. Even assigning much more memory does only delay but not stop it.

Upvotes: 0

Views: 761

Answers (1)

JQian
JQian

Reputation: 226

You are using stop-the-world GC (probably Parallel Scavenge).This exception is because GC takes too much time, which maybe more than 98% of total execution time. In this case, JVM kills the process as no real work is being done.

The solutions could be:

  1. Try another type of GC, such as Concurrent Mark Sweep, which is not stop-the-world GC;
  2. Try larger memory, so GC is not that frequent;
  3. Ignore this GC time limitation by using -XX:-UseGCOverheadLimit, which may cause problems as JVM keeps working on GC instead of real work;
  4. As mentioned, dump the memory trace with -XX:+HeapDumpOnOutOfMemoryError and analyze the trace.

A little more explanation why heap is not full but GC over limit (all these are guesses, and more traces needed to make sure the causes): this can be

  1. too small young generation or most of objects survive from minor GC, so GC happens too frequently and/or to spends long time moving objects (this maybe tuned by changing young generation size on heap, or changing objects tenure rate by some JVM flag);
  2. too small old generation size that the objects survived from minor GC cannot be fitted into old generation, which causes frequent major GC (or full heap GC).

Upvotes: 2

Related Questions