1

We are using Java as middleware to communicate with db - but nowadays we are getting CPU high around 400%. We have installed the JVM to monitor the issue - and found this error - could you please suggest us to improve this? I have seen these,

  1. [Quick solution] Increase memory (my current server having 16GB ram, quad-core processor) -- any suggestion how much need to increase?

  2. What are the objects in the application that occupy large portions of the heap? -- how to identify this as very basic knowledge on Java, is there any tool which would help me to identify this?

  3. In which parts of the source code are these objects being allocated? -- how to identify this as very basic knowledge on Java, is there any tool which would help me to identify this?

    o

rg.glassfish.jersey.server.ContainerException: java.lang.OutOfMemoryError: GC overhead limit exceeded …httpserver.GrizzlyHttpContainer$ResponseWriter.rethrow(GrizzlyHttpContainer.java:318) …httpserver.GrizzlyHttpContainer$ResponseWriter.failure(GrizzlyHttpContainer.java:300) …lassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:486) org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:317) org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) org.glassfish.jersey.internal.Errors.process(Errors.java:315) org.glassfish.jersey.internal.Errors.process(Errors.java:297) org.glassfish.jersey.internal.Errors.process(Errors.java:267) …ssfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:292) org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1139) …ersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:375) org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224) …sh.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591) …sfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) java.lang.Thread.run(Thread.java:748) caused by java.lang.OutOfMemoryError: GC overhead limit exceeded

trincot
  • 317,000
  • 35
  • 244
  • 286
Haris
  • 11
  • 2
  • You could profile the app and see if there is a specific type of object that uses a lot of memory. If could be due to stale objects staying in memory because you keep a reference to them somewhere in your code. Or your app may indeed require more memory for what's it's doing. – assylias Jan 14 '21 at 04:24
  • 16gb is an important ram quantity. What is doing your web application: File processing, reports generation, extracting thousands of rows from database? Is an rest api or a web classic java monolith? Java version? Server version? S.O (Windows may be the problem), Cloud/Onpremise? Disk space? Used frameworks? Update your question with this information In order to be able to better help you – JRichardsz Jan 14 '21 at 04:49

1 Answers1

0

These kinds of mistakes are terrifying, because to find the real cause is complicated, and a intermediate java knowledge is required.

It never hurts a bit of documentation:

Sudden change

If it is a sudden change, this may be the cause. If you have a intermediate control and monitor of your infrastructure, you should be able to detect when this problem started:

  • after the release of a new version of java application
  • after an upgrade of web server
  • after an upgrade of the operative system
  • after new version of database (e.g oracle 11 > 12)
  • after low level changes in the database(ram, disk, etc)
  • more users than expected. Maybe concurrent users

If some of the previous causes sounds familiar to you, just revert it and validate if is the cause of a resource (memory) exhaustion.

Legacy

In some cases, legacy servers or applications (installed several years ago) could be the cause of these kind of problems:

  • temporary file are not deleted
  • the disk reached its maximum
  • deprecated java libraries

Try to upgrade the web server and deploy again your application. Also if your application is agnostic, try to deploy to another servers just to try.

A huge number of rows

Some times [GC overhead limit exceeded] is related to this error:

java.lang.OutOfMemoryError: Java heap space

Which is related with ResultSets that have a large number of rows or large values. As a result it can not allocate heap space in the JVM for the memory required.

If this is the case, try with:

stmt.setFetchSize

Sources:

Source Code Manual Inspection

This snippet is able to replicate your error:

Map<Integer, String> dataMap = new HashMap<>();
Random r = new Random();
while (true) {
    dataMap.put(r.nextInt(), String.valueOf(r.nextInt()));
}

Try to review class by class in order to find blocks like the snippet.

Monitor Tools

There are several tools. Its usage is not so easy. I advice you choose one and test it with a simple application like:

  • swing app
  • spring boot minimal rest api
  • web deployed in tomcat

If you are able to understand how it works, use it in your real application.

Visual VM

visual-vm

visual-vm

As you can see, this tool is able to scan all your classes and get relevant metadata like: live instances, memory, etc

Sources:

Java Mission Control

Java Flight Recorder and JDK Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis

Java Mission Control

Sources:

Eclipse Profiler

In almost all java web servers, remote debug is a feature.

If you can configure it, you could try the eclipse profiles. You will see all the classes of your application:

enter image description here

Sources:

JRichardsz
  • 14,356
  • 6
  • 59
  • 94