Java OutOfMemoryError : GC overhead limit exceeded Example
This is continuing article of out of memory error explanation. In this post I will provide how to reproduce Java OutOfMemoryError : GC overhead limit exceeded. We will see how to recreate and what are the impact in monitoring tools.
I have used only JVM 1.8 x64 on windows 7 x64/8gb ram/ 2.5Ghz Core i5 laptop.
Tools :
IDE : Eclipse
Profiling/Monitoring tool :
Now, for the GC overhead error, it is easily untestable , due to GC is unable to free up the heap with its best efforts. The main cause is, GC is taking 98% of CPU time to cleanup heap where heap is not feeing up more than 2%. In our example, we will see GC overhead multiple time as heap is occupied after certain amount of item entry.
Again, to know about the error, you can visit this original post.
Scenario:
Very simple scenario, I am adding a string in a map(it is costly, if we use array list, it will take more time) in an infinite loop.
Code :
And from main method, call this.
2. -UseParNewGC -XX:+UseConcMarkSweepGC
3. -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
4. -XX:+UseG1GC
5. -Xincgc
6. -XX:+UseSerialGC
7. -XX:+UseParallelGC
Error analysis in console :
Error Occurred after 1488049 items added. We can see multiple OOM messages for each try by GC.
Dump Analysis in Visual VM (created at OOM ): I am using one of errors
Summary :
Top contributors :
Visual VM Monitoring :
Heap :
JConsole Monitoring : (overall)
Yourkit Monitoring :
CPU usages :
Heap :
Non Heap :
Please comment if you have any question.
Thanks.. :)
I have used only JVM 1.8 x64 on windows 7 x64/8gb ram/ 2.5Ghz Core i5 laptop.
Tools :
IDE : Eclipse
Profiling/Monitoring tool :
1. Visual VM
2. Jconsole (optional)
3. Yourkit (optional)
I am using some JVM flags to get detail GC information and monitoring via JMX. Please see this post in step 1 for detail.
2. Jconsole (optional)
3. Yourkit (optional)
I am using some JVM flags to get detail GC information and monitoring via JMX. Please see this post in step 1 for detail.
I am using these flags here (xmx to limit heap to have quick error)
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=3000
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=localhost
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\OOM
-Xmx100m
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=3000
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=localhost
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\OOM
-Xmx100m
Now, for the GC overhead error, it is easily untestable , due to GC is unable to free up the heap with its best efforts. The main cause is, GC is taking 98% of CPU time to cleanup heap where heap is not feeing up more than 2%. In our example, we will see GC overhead multiple time as heap is occupied after certain amount of item entry.
Again, to know about the error, you can visit this original post.
Scenario:
Very simple scenario, I am adding a string in a map(it is costly, if we use array list, it will take more time) in an infinite loop.
Code :
public class GCOverheadOOM {
private static Map aMap = new HashMap();
public static void createGCOverheadOOM(){
int i = 0;
try{
while (true) {
aMap.put(i, "Shantonu adding String");
System.out.println("Total Items "+i++);
}
}catch(Throwable e){
System.err.println("\nError after adding "+ aMap.size()+" items");
e.printStackTrace();
}
}
}
private static Map aMap = new HashMap();
public static void createGCOverheadOOM(){
int i = 0;
try{
while (true) {
aMap.put(i, "Shantonu adding String");
System.out.println("Total Items "+i++);
}
}catch(Throwable e){
System.err.println("\nError after adding "+ aMap.size()+" items");
e.printStackTrace();
}
}
}
And from main method, call this.
GCOverheadOOM.createGCOverheadOOM();
Note : As this is a GC related error (overhead) , this error fully depends on GC algorithm. This code generates the error in default or parallel GCs. When I used different, I got slightly different one. I have tried following jvm flags to select GC algorithm. Each at a one time
1. -XX:+UseParallelGC -XX:-UseParallelOldGC2. -UseParNewGC -XX:+UseConcMarkSweepGC
3. -XX:+UseParNewGC -XX:+UseConcMarkSweepGC
4. -XX:+UseG1GC
5. -Xincgc
6. -XX:+UseSerialGC
7. -XX:+UseParallelGC
Oracle has clear indication here.
Error analysis in console :
Error Occurred after 1488049 items added. We can see multiple OOM messages for each try by GC.
Dump Analysis in Visual VM (created at OOM ): I am using one of errors
Summary :
Top contributors :
Visual VM Monitoring :
GC before ending :
Heap :
JConsole Monitoring : (overall)
Yourkit Monitoring :
CPU usages :
Heap :
Non Heap :
Please comment if you have any question.
Thanks.. :)