Analysis of GC Overhead Limit Exceeded

Sahil Mutneja
3 min readDec 8, 2017

So the idea over here is to analyze the scenario wherein the java service runs out of memory resulting it not to perform and entertain any further operation and requests. The error, related to it, that many of us might have encountered is :

GC Overhead Limit Exceeded : java.lang.OutOfMemoryError Analysis

The same then gets extended to further error like

WARN [2017–12–04 11:10:37,674] com.zaxxer.hikari.pool.ProxyConnection: hibernate — Connection com.mysql.jdbc.JDBC4Connection@6aaf1f96 marked as broken because of SQLSTATE(08003), ErrorCode(0)
! java.lang.OutOfMemoryError: GC overhead limit exceeded
! Causing: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.

The message above basically means that for some reason the garbage collector is taking an excessive amount of time to collect all the unused objects from the heap and in turn recovers very little memory in each run.

This effectively means that most of the time gets spent doing the garbage collection and as a result the main program progress goes for a toss. At this point, in order for us to take some action, JVM throws this Error so that the end user can diagnose the problem and fix it.

Analyzing the JVM in your machine

One way to visualize the usage of the JVM is by running the Java Visual VM which will give you insights about the heap size and the usage of it as the requests are hitting the service. In order to run the tool, go to the location mentioned below and double click the executable file which goes by the name jvisualvm:

Go to the location and open it :
/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/jvisualvm

A terminal window gets opened along with the UI wherein one can check the heap allocated, used and unused size. Attached below is the screenshot of the same, for a sample java service

Whenever the request hits the service and a big object gets returned as part of the response, the value that increases is the memory(used heap) and along with it, is the CPU usage. The important point to note here is that the size of the response proportionally determines the usage of the heap as the object needs to be saved in the memory first before it gets returned. This means, for a given API if large amount of data is getting returned and multiple requests for the same API starts coming in, then the chances of service throwing this error are pretty high.

! java.lang.OutOfMemoryError: GC overhead limit exceeded

In the tool, there is an option to perform force garbage collection as well. Once the same is clicked, the heap usage will show a significant dip as displayed in the image below. Refer time around 12:02 AM.

Heap Usage Visualisation

This will also help to understand if there are any leaks in the service which even upon running the GC are not getting removed.

Taking care of the problem

Normally, if the design of the application is correct i.e. memory leaks are well been taken care of, then one option to solve the problem is to set a higher -Xmx value in order to allow the application to play around with additional heap size. The way we do it is :

-Xms1024M -Xmx2048M

here -Xms is for minimum limit and -Xmx is for maximum limit

Also, it’s always good to use the existing objects whenever possible in order to save memory and utilize the space which already is getting used.

In addition to it, as far as the REST Endpoints and the size of the response is concerned, it’s advised to have server side pagination to make the client server communication quick and smooth and to take care of the load on the server and the memory which is getting used.

Will keep the space updated with more and more relevant information.

Cheers !!

--

--

Sahil Mutneja

A techie based out of Bengaluru, India who loves to travel, explore and learn!