Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Java Garbage Collector appear to do an aggressive run shortly after doing a less aggressive one?

While monitoring a java program with VisualVM, I noticed an interesting pattern in the garbage collector's behaviour. It seems like very often, right after doing a 'normal' garbage collection run, the GC does a second, much more cpu intensive run, which appears to have no additional effect (The used heap after the more aggressive run is about the same as it is after the lighter run).

I've indicated on VisualVM's output where you can see the garbage collector runs and corresponding heap-usage changes.

interesting garbage collector behaviour

My question is basically what is the Garbage collector doing here and why? What is causing it to attempt these really cpu-intensive runs when there's plenty of free memory, and no observable benefit versus the lighter runs? Or am I misinterpreting the graph?

The performance of the program isn't really affected, I'm just curious.

like image 502
Gordon Bailey Avatar asked Apr 01 '13 21:04

Gordon Bailey


People also ask

How often does the garbage collector run in Java?

That is, every time you allocate a small block of memory (big blocks are typically placed directly into "older" generations), the system checks whether there's enough free space in the gen-0 heap, and if there isn't, it runs the GC to free up space for the allocation to succeed.

What causes major garbage collection in Java?

The Old Generation is used to store long surviving objects. Typically, a threshold is set for young generation object and when that age is met, the object gets moved to the old generation. Eventually the old generation needs to be collected. This event is called a major garbage collection.

How does Java garbage collector work when does it run?

In Java, garbage collection happens automatically during the lifetime of a program. This eliminates the need to de-allocate memory and therefore avoids memory leaks. Java Garbage Collection is the process by which Java programs perform automatic memory management.

What hinders the performance and causes garbage collection to run for minutes?

The most important factor affecting garbage collection performance is total available memory. Because collections occur when generations fill up, throughput is inversely proportional to the amount of memory available.

What causes long garbage collection time?

If your application's object creation rate is very high, then to keep up with it, the garbage collection rate will also be very high. A high garbage collection rate will increase the GC pause time as well. Thus, optimizing the application to create fewer objects is THE EFFECTIVE strategy to reduce long GC pauses.


1 Answers

Looking at graphs is a good thing to get an overview of GC runs but if you want to study why the GC is running in a particular moment, you need to dig deep into the GC logs.

Enable full GC logging, start collecting jstat as well. Focus on those times where you see unexpected GC cycles and trace them back in the logs. What do you see there? Try to see :

  • is it Full or minor GC?
  • what are occupations of eden, perm, oldGen, survivor spaces, etc?
  • what are allocation rates, live data set size, promotion rates in those intervals?
  • etc.

Answering these questions could lead you to the problem of why the GC is running.

UPDATE: you can find technical details on howto tune GC e.g. in: Is there a cookbook guide for GC problems?

like image 159
Aleš Avatar answered Oct 18 '22 16:10

Aleš