Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Garbage Collector taking too much CPU Time

I've developed a Web Application which process a huge amount of data and takes a lot of time to complete?

So now I am doing profiling of my application and I noticed one very bad thing about GC.
When a Full GC occurred it stops all process for 30 - 40 secs.

I wonder if there is any way to improve this. I don't want to waist my CPU's that much time only in GC. Below are some details that can be useful:

  1. I am using Java 1.6.0.23
  2. My Application takes 20 GB max memory.
  3. A full GC occur after every 14 minutes.
  4. Memory Before GC is 20 GB and after GC is 7.8 GB
  5. Memory used in CPU (i.e. shown in task manager) is 41 GB.
  6. After process completed(JVM is still running) Used memory 5 GB and free memory 15 GB.
like image 768
NIVESH SENGAR Avatar asked Mar 09 '12 09:03

NIVESH SENGAR


4 Answers

There are many algorithms that modern JVM's use for garbage collection. Some algorithms such as reference counting are so fast, and some such as memory copying are so slow. You could change your code so that help the JVM to use the faster algorithms most of the time.

One of the fastest algorithms is reference counting, and as the name describes, it counts references to an object, and when it reaches zero, it is ready for garbage collection, and after that it decreases reference count to objects referenced by the current GCed object.

To help JVM to use this algorithm, avoid having circular references (object A references B, then B references C, C references D ...., and Z references A again). Because even when the whole object graph is not reachable, none of the object's reference counters reaches zero.

You could only just break the circle when you don't need the objects in the circle any more (by assigning null to one of references)....

like image 66
Amir Pashazadeh Avatar answered Sep 28 '22 08:09

Amir Pashazadeh


If you use 64 bit architecture add:

-XX:+UseCompressedOops 64bit addresses are converted to 32bit

Use G1GC instead of CMS:

-XX:+UseG1GC - it use incremental steps

Set the same initial and max size: -Xms5g -Xmx5g

Tune parameters (just example):

-XX:MaxGCPauseMillis=100 -XX:GCPauseIntervalMillis=1000

See Java HotSpot VM Options Performance Options

like image 25
Andrzej Jozwik Avatar answered Sep 28 '22 08:09

Andrzej Jozwik


Either improve app by reusing resources or kick-in System.gc() yourself in some critical regions of the app (which is not guaranteed to help you). Most likely you have a memory leak somewhere that you have to investigate and consequently restructure the code.

like image 25
darijan Avatar answered Sep 28 '22 07:09

darijan


The fewer things you new, the fewer things need to be collected.

Suppose you have class A. You can include in it a reference to another instance of class A. That way you can make a "free list" of instances of A. Whenever you need an A, just pop one off the free list. If the free list is empty, then new one.

When you no longer need it, push it on the free list.

This can save a lot of time.

like image 28
Mike Dunlavey Avatar answered Sep 28 '22 07:09

Mike Dunlavey