Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What triggers a gen2 garbage collection?

Tags:

I have an odd situation I am trying to figure out.

The Genesis:

I am running my program on a physical machine with 16 cores and 128GB of RAM. I am trying to determine why it is not using all available cores, typically it uses 20-25% CPU on average (so 4-5 cores of the 16). When I look at performance counters they show on the order of 60-70% Time in Garbage Collection.

For reference, I am using .NET Framework 4 and the TPL (Parallel.ForEach) to thread the performance-intensive portion of my program. I am limiting the number of threads to the number of cores.

The Problem:

I was creating a large number of objects, far too many for the garbage collector to handle efficiently and thus it spent a large amount of time in the garbage collector.

The Simple Solution thus far:

I am introducing object pooling to reduce the pressure on the garbage collector. I will continue pooling objects to improve performance, already pooling some objects reduced garbage collection from 60-70% of time to 45% of time and my program ran 40% faster.

The Nagging Question (the one I hope you will answer for me):

My program when running uses at most 14GB of the available RAM, compared to 128GB of RAM this is quite small. Nothing else is running on this machine (it is purely a testbed for me) and there is plenty of RAM available.

  • If there is plenty of RAM available, why are any gen2 (or full) collections occurring at all? A fairly large number of these gen2 collections (in the thousands) are occurring. i.e. how is it determining the threshold to start a gen2 collection?
  • Why doesn't the garbage collector simply delay any full collections until pressure on physical RAM reaches a higher threshold?
  • Is there any way I can configure the garbage collector to wait for a higher threshold? (i.e. not bother collecting at all if no necessary)

EDIT:

I am already using the option to use the server garbage collector ... what I need to know is what is triggering a gen2 collection, not that the server garbage collector is better (I already know that).

like image 653
Jeffrey Cameron Avatar asked May 26 '11 23:05

Jeffrey Cameron


People also ask

What triggers garbage collection?

Common triggers for garbage collection are Eden space being full, not enough free space to allocate an object, external resources like System. gc(), tools like jmap or not enough free space to create an object. Interested in a solution that helps you keep an eye on memory usage?

What are generations in garbage collector Gen 0 1 and 2 )?

Generation 0 identifies a newly created object that has never been marked for collection. Generation 1 identifies an object that has survived a GC (marked for collection but not removed because there was sufficient heap space) Generation 2 identifies an object that has survived more than one sweep of the GC.

How does generational garbage collection work?

Generational garbage collection schemes are based on the empirical observation that most objects die young. In generational garbage collection two or more allocation regions (generations) are kept, which are kept separate based on object's age.

When and how garbage collector is invoked?

When the JVM doesn't have necessary memory space to run, the garbage collector will run and delete unnecessary objects to free up memory. Unnecessary objects are the objects which have no other references (address) pointing to them.


1 Answers

As I recall, the Client GC is the default. My experience with it is that it doesn't let the heap get very large before collecting. For my heavy duty processing applications, I use the "server" GC.

You enable the server GC in your application configuration file:

<?xml version ="1.0"?> <configuration>   <runtime>     <gcServer enabled="true"/>   </runtime> </configuration> 

That makes a huge difference in performance for me. For example, one of my programs was spending upwards of 80% of its time in garbage collection. Enabling the server GC dropped that to just a little over 10%. Memory usage went up because the GC let it go, but that's fine for most of my applications.

Another thing that will cause a Gen 2 collection is the Large Object Heap. See CLR Inside Out: Large Object Heap Uncovered. In a nutshell, if you exceed the LOH threshold, it will trigger a Gen 2 collection. If you're allocating a lot of short-lived large objects (about 85 kilobytes), this will be a problem.

like image 171
Jim Mischel Avatar answered Sep 28 '22 03:09

Jim Mischel