The java.lang.OutOfMemoryError: GC overhead limit exceeded is another type of OutOfMemoryError in Java which comes when JVM spent too much time doing garbage collection without any success. For example, if almost 98% of CPU for a Java process is busy doing GC and reclaims very less amount of Java heap space around 2%, then JVM throws "java.lang.OutOfMemoryError: GC overhead limit exceeded" error. Though, the definition of 98% CPU time may vary between different Garbage collectors and different JVM versions.
Unlike java.lang.OutOfMemoryError: Java heap space and java.langOutOfMemory: Permgen space, is not so frequent and you will rarely encounter this error in your Java application, but this also denotes resource exhaustion.
Btw, if you are thinking that there is only one type of OutOfMemoryError in Java which comes when there is not enough memory in heap to create objects in heap, you are wrong. There are different types of OutOfMemoryError in Java and each denotes a different type of resource problems e.g.
java.lang.OutOfMemoryError: Java heap space
This error means not enough heap memory to create new objects.
java.lang.OutOfMemoryError: Permgen space
This error means not enough memory in the permanent generation of the heap to load class metadata.
java.lang.OutOfMemoryError: Direct buffer memory
means not enough heap memory to allocate to direct byte buffer.
java.lang.OutOfMemoryError: unable to create new native thread
means your application has exceeded the limit to create threads.
java.lang.OutOfMemoryError: Metaspace
this error is Java 8 equivalent of Permgen error because the Permanent generation has been removed in Java 8 and a new Metaspace is introduced.
Now, let's try to find out some of the possible causes of the "GC overhead limit exceeded" error in JVM.
1) find out if you have increased the size of your application cache(if any) but not increased -Xmx (max heap size setting) accordingly.
2) find out if you have introduced a new cache or caching data structure e.g. Collection classes like HashMap which stores object in memory.
As a general best practice to avoid resource exhaustion you should always use the bounded cache as in the case of unbounded cache you may run out of memory but with the bounded cache, you don't grow without your limit.
And, if you are serious about improving your advanced JVM skill and learn things like taking and analyzing heap dumps then highly recommend you to join Java Application Performance and Memory Management course on Udemy.
It's one of the advanced courses for Java programmers to learn more about Performance and Memory management including troubleshooting memory leaks in Java.
But if your application genuinely needs more memory may be because of increased cache size or the introduction of new caches then you can do the following things to fix java.lang.OutOfMemoryError: GC overhead limit exceeded in Java:
1) Increase the maximum heap size to a number that is suitable for your application e.g. -Xmx=4G. Remember, if you are running on 32-bit JVM you cannot set a maximum heap size of more than 2G on different operating systems e.g. Windows, Linux, or Solaris.
If your application needs more memory, it's better to switch to a 64-bit Java Virtual Machine. If you try to provide more than 2G to a 32-bit JVM, it will not start and throw invalid heap size error.
2) If you are not using already then try using -XX:+UseConcMarkSweepGC Garbage collector in your Java application. This is one of the best garbage collectors available in JVM prior to Java 7. From Java 7 onward you can also use the G1 Garbage collector, which will also become the default garbage collector from Java 9.
If you want to learn more about different types of Garbage collectors and how they work, I suggest you read a good book on JVM internals and Java performance tuning e.g. you can choose from definitive guide to Java performance by Scott Oaks or a more recent Java performance companion from Charlie hunt, both are great book to learn JVM internals and GC.
3) Avoid creating too much garbage and reuse temporary objects if you can. This should be the last thing you should do because reusing temporary objects may create subtle issues. make sure anything you reuse is safe and can be reusable in terms of functionality especially in a concurrent and multi-threading environment.
Don't try to reuse static variables without proper synchronization to avoid any surprise race conditions in your Java application.
Btw, if you are thinking that there is only one type of OutOfMemoryError in Java which comes when there is not enough memory in heap to create objects in heap, you are wrong. There are different types of OutOfMemoryError in Java and each denotes a different type of resource problems e.g.
java.lang.OutOfMemoryError: Java heap space
This error means not enough heap memory to create new objects.
java.lang.OutOfMemoryError: Permgen space
This error means not enough memory in the permanent generation of the heap to load class metadata.
java.lang.OutOfMemoryError: Direct buffer memory
means not enough heap memory to allocate to direct byte buffer.
java.lang.OutOfMemoryError: unable to create new native thread
means your application has exceeded the limit to create threads.
java.lang.OutOfMemoryError: Metaspace
this error is Java 8 equivalent of Permgen error because the Permanent generation has been removed in Java 8 and a new Metaspace is introduced.
Now, let's try to find out some of the possible causes of the "GC overhead limit exceeded" error in JVM.
Possible cause of GC overhead limit exceeded OutOfMemoryError in Java
If you suddenly start getting java.lang.OutOfMemoryError: GC overhead limit exceeded in your Java application then there are two possibilities either your application have developed a memory leak or you have introduced code changes which demand more memory and tend to store more objects in memory which is preventing Garbage collector to free memory from the heap. To verify this you can do the following things1) find out if you have increased the size of your application cache(if any) but not increased -Xmx (max heap size setting) accordingly.
2) find out if you have introduced a new cache or caching data structure e.g. Collection classes like HashMap which stores object in memory.
As a general best practice to avoid resource exhaustion you should always use the bounded cache as in the case of unbounded cache you may run out of memory but with the bounded cache, you don't grow without your limit.
And, if you are serious about improving your advanced JVM skill and learn things like taking and analyzing heap dumps then highly recommend you to join Java Application Performance and Memory Management course on Udemy.
It's one of the advanced courses for Java programmers to learn more about Performance and Memory management including troubleshooting memory leaks in Java.
Suggestions to fix java.lang.OutOfMemoryError: GC overhead limit exceeded
One of the first things you can do to solve java.lang.OutOfMemoryError: GC overhead limit exceeded is to find out whether you have a memory leak or not because if you have memory leak changing heap sizes will just delay the occurrence of java.lang.OutOfMemoryError: GC overhead limit exceeded, it won't eliminate it.But if your application genuinely needs more memory may be because of increased cache size or the introduction of new caches then you can do the following things to fix java.lang.OutOfMemoryError: GC overhead limit exceeded in Java:
1) Increase the maximum heap size to a number that is suitable for your application e.g. -Xmx=4G. Remember, if you are running on 32-bit JVM you cannot set a maximum heap size of more than 2G on different operating systems e.g. Windows, Linux, or Solaris.
If your application needs more memory, it's better to switch to a 64-bit Java Virtual Machine. If you try to provide more than 2G to a 32-bit JVM, it will not start and throw invalid heap size error.
2) If you are not using already then try using -XX:+UseConcMarkSweepGC Garbage collector in your Java application. This is one of the best garbage collectors available in JVM prior to Java 7. From Java 7 onward you can also use the G1 Garbage collector, which will also become the default garbage collector from Java 9.
If you want to learn more about different types of Garbage collectors and how they work, I suggest you read a good book on JVM internals and Java performance tuning e.g. you can choose from definitive guide to Java performance by Scott Oaks or a more recent Java performance companion from Charlie hunt, both are great book to learn JVM internals and GC.
3) Avoid creating too much garbage and reuse temporary objects if you can. This should be the last thing you should do because reusing temporary objects may create subtle issues. make sure anything you reuse is safe and can be reusable in terms of functionality especially in a concurrent and multi-threading environment.
Don't try to reuse static variables without proper synchronization to avoid any surprise race conditions in your Java application.
That's all about how to fix this OutOfMemoryError in your Java application. The " java.lang.OutOfMemoryError: GC overhead limit exceeded" is one of the rare errors in Java application, but when it comes it takes some time to go away because finding the actual cause is not very straight forward. You need a combination of code analysis as well as load analysis for your application. It may also be the time for capacity planning for your application.
Other Java Troubleshooting Guides you may like to explore
Thanks for reading this article so far. If you like this tutorial then please share it with your friends and colleagues. If you have any questions or suggest then please drop a comment.
Other Java Troubleshooting Guides you may like to explore
- How to solve java.sql.BatchUpdateException: String or binary data would be truncated (guide)
- How to solve java.lang.ClassNotFoundException: com.mysql.jdbc.Driver error? (hint)
- 5 Reasons of NoClassDefFoundError in Java? (tutorial)
- How to fix Caused By: java.lang.NoClassDefFoundError: org/apache/log4j/Logger (solution)
- Cause of "java.lang.SecurityException: Missing required Permissions manifest attribute in main jar" [solution]
- How to fix "illegal start of expression" compile time error in Java? (tutorial)
- How to fix "Error: Could not find or load main class" in Eclipse? (guide)
- How to fis unable to find certification path error in Java SSL? (guide)
- 10 common reasons of java.lang.NumberFormatException in Java? (tutorial)
- java.sql.SQLException: No suitable driver found for 'jdbc:mysql://localhost:3306/mysql [Solution]
- How to solve "variable might not have initialized" compile time error in Java? (answer)
- How to deal with "No JVM installation found, please install 64-bit JDK" error? (solution)
- How to fix 'javac' is not recognized as an internal or external command (solution)
- How to avoid ConcurrentModificationException in Java? (tutorial)
- How to solve "could not create the Java virtual machine" error in Java? (solution)
- Common reasons of java.lang.ArrayIndexOutOfBoundsException in Java? (solution)
- java.lang.ClassNotFoundException : org.Springframework.Web.Context.ContextLoaderListener (solution)
- java.sql.SQLServerException: The index 58 is out of range - JDBC (solution)
- Fixing java.lang.unsupportedclassversionerror unsupported major.minor version 50.0 (solution)
- java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory error (solution)
- Cause and solution of "class, interface, or enum expected" compiler error in Java? (fix)
- How to connect to MySQL database in Java? (tutorial)
- How to solve java.lang.classnotfoundexception oracle.jdbc.driver.oracledriver? (solution)
Thanks for reading this article so far. If you like this tutorial then please share it with your friends and colleagues. If you have any questions or suggest then please drop a comment.
Good info javin
ReplyDeleteGlad that you find information useful Saurav. Thanks Javin
ReplyDelete