How to make .NET garbage collection less frequent?

I have an application that processes a large number of small objects, for example. 2000 messages per second. One message is approximately 100 bytes, and maybe less. The application was run for 6 and a half hours under load, and during this time he had collections of 264,416 0 th , 166,699 1 st gen and 69,608 2 nd gen. These are 11.6, 7.3 and 3 collections per second, respectively.

The question is how to make garbage collection less frequent?

UPD: An application is a server that receives messages from WCF using several processing modules and storing them in a database.

I got the impression that the GC should adapt and increase the size of the generation after a while, but this is clearly not the case.

UPD 2 : as suggested by leppie GC in server mode, it really makes the collection 10 times smaller. It also appears (as Richter describes) that frequent collections are not so bad.

+8
garbage-collection
source share
6 answers

You will get about 10 times less GC if you include gcServer="true" in app.config. But note that this does not improve performance, and you are likely to increase the latency in your application if it is a desktop application.

Here is the app.config setup:

 <runtime> <gcServer enabled="true"/> </runtime> 
+4
source share

Why do you think this affects you? In particular, gen-0 collections are very, very cheap - and should be encouraged.

I would rather look at "What can cause some of these queries to avoid gen-0 in gen-1; am I clinging to any object unnecessarily, for example, through an event?".

Of course, one more thing you need to pay attention to: are there any places where you can avoid creating unnecessary objects, for example:

  • Are you doing string concatenation in a loop, which could be StringBuilder instead?
  • any moderate to large collections that can be initialized with the correct length to avoid redistribution?
  • any buffers from scratch that can be reused? for example, do you do a lot of coding work that briefly uses byte[] in a method where this byte[] can be passed as a zero region or captured from a pool?
  • any other things that can be cached and reused - for example, new Regex("some literal") , created inside a method that can be entered into a static field, and also compiled for performance
  • any intense string parsing that interning can use? (not necessarily a built-in interner though)
+9
source share

The number of gen # 0 collections is roughly equivalent. Fast # 1 and # 2 are too high, these objects live too long. Perhaps you put them in a queue and they sit there for a while before being processed. Otherwise, a sign that you are close to satiety. In short, combining buffers can help them faster.

+1
source share

Have you considered using value types instead of reference types? This may be a good option if the “objects” are temporary and are only needed during processing. Value types (structures) are allocated on the stack and, therefore, do not need assembly (for example, class instances).

+1
source share

Your problem is not the garbage collector, but that you have too many objects. If your process is serial and you do not have to have all of these objects in memory at the same time, try reusing them instead of creating and destroying them. If performance is your goal, use other types of structures to store data, such as arrays, memory stream, or other, but not collections of objects.

0
source share

Perhaps you should consider using a pool of objects or weathercocks. More reusable objects often result in less garbage and make GC less frequent.

0
source share

All Articles