How to avoid garbage collection in a .NET application in real time?

I am writing a C # financial application that receives messages from the network, transfers them to another object according to the type of message, and finally applies the business logic of the application to them.

The fact is that after applying business logic, I am sure that I will no longer need this instance. Instead of waiting for the garbage collector to free them, I would like to explicitly “delete” them.

Is there a better way to do this in C #, should you use an object pool to always reuse the same set of instances, or is there a better strategy.

The goal is to avoid garbage collection for the use of any processor during a critical process.

+11
garbage-collection c # real-time finance
Sep 17 '08 at 16:54
source share
13 answers

Do not delete them immediately. Calling a garbage collector for each object is a bad idea. Usually you really don't want to mess with the garbage collector at all, and even the critical processes of the time are just race conditions that await if they are so sensitive.

But if you know that you will have a busy or easy loading period for your application, you can try the more general GC.Collect () when you reach the light period to encourage cleaning until the next busy period.

+21
Sep 17 '08 at 16:57
source share

See here: http://msdn.microsoft.com/en-us/library/bb384202.aspx

You can tell the garbage collector that you are doing something critical at the moment, and it will try to be with you.

+18
Sep 17 '08 at 16:59
source share

You fall into yourself - use the pool of objects and reuse these objects. The semantics of calls to this object should be hidden behind the facade of the factory. You will need to create a pool in a certain way. Perhaps double the size every time it reaches the limit - an algorithm with high humidity or a fixed percentage. I would strongly advise you not to call GC.Collect ().

When the load on your pool becomes low enough, you can compress the pool, and this will eventually cause garbage collection - let the CLR worry about it.

+11
Sep 17 '08 at 17:35
source share

Trying to guess the garbage collector a second time is usually a very bad idea. On Windows, the garbage collector is one generation old , and you can rely on it to be quite efficient. There are some noted exceptions to this general rule - the most common occurrence is a one-time event that, as you know, a fact would cause many old objects to die - as soon as the objects advance to Gen2 (the longest lived) they tend to hang out.

In the case when you mention, you say that you generate several short-lived objects - this will lead to collections of Gen0. This happens quite often, and they are most effective. You can avoid them if you want if you have a reusable pool of objects, but it’s best to make sure that the GC is a performance issue before doing this. The CLR profiler is a tool for this.

It should be noted that the garbage collector is different on different .NET platforms - on a compact structure (which works on the Xbox 360 and on mobile platforms) this is GC without generation, and therefore you should be much more careful about what kind of garbage you create.

+7
Sep 17 '08 at 17:30
source share

Forcing GC.Collect () is usually a bad idea; leave GC to do what it does best. It seems that the best solution would be to use a pool of objects that can be expanded if necessary. I have successfully used this template.

Thus, you avoid not only garbage collection, but also the regular distribution cost.

Finally, are you sure the GC is causing you problems? You should probably measure and prove this before you implement any persistent solutions — you can do yourself an unnecessary job!

+5
Sep 17 '08 at 17:02
source share

"The goal is to avoid garbage collection in order to use any processor during a critical process."

Q: If it’s critical in time, do you mean that you are listening to some esoteric piece of hardware and you cannot afford to skip the interrupt?

A: If so, C # is not a used language, for this you need Assembler, C or C ++.

Q: If by Critical time you mean that there are a lot of messages in the pipe, and you do not want the garbage collector to slow down?

A: If you are so worried. By the sounds of things that your objects are very short-lived, this means that the garbage collector will recycle them very quickly without any noticeable performance lag.

However, the only way to know for sure is to check it, configure it to start nightly processing a constant stream of test messages, I will be stunned if you can find out the performance statistics when the GC starts up (and even if you notice this, I will be even more surprised if it really matters).

+5
Feb 09 '09 at 17:09
source share

Get a good understanding and feel how the garbage collector behaves, and you will understand why what you think here is not recommended. if you really don't like the CLR to waste time reordering objects in memory.

+3
Sep 17 '08 at 17:10
source share

If this is absolutely critical time, you should use a deterministic platform such as C / C ++. Even a call to GC.Collect () will generate processor cycles.

Your question begins with the suggestion that you want to save memory, but get rid of objects. This is spatial critical optimization. You need to decide what you really want, because the GC optimizes this situation better than a person.

+2
Sep 17 '08 at 17:07
source share

From the sound of this, it seems you are talking about deterministic finalization (destructors in C ++) that does not exist in C #. The closest you'll find in C # is a one-time pattern. You basically implement the IDisposable interface.

The basic template is as follows:

public class MyClass: IDisposable { private bool _disposed; public void Dispose() { Dispose( true ); GC.SuppressFinalize( this ); } protected virtual void Dispose( bool disposing ) { if( _disposed ) return; if( disposing ) { // Dispose managed resources here } _disposed = true; } } 
+2
Sep 17 '08 at 21:43
source share

How intense is the application? I wrote an application that captures 3 sound cards (Managed DirectX, 44.1KHz, Stereo, 16 bits) in 8KB blocks and sends 2 of 3 streams to another computer via TCP / IP. The user interface displays a sound level meter and a (smooth) title / artist scroll for each of the three channels. It works on a PC with XP, 1.8 GHz, 512 MB, etc. The application uses about 5% of the processor.

I was not left in a manual call to GC methods. But I had to set up a few things that were wasteful. I used the RedGate Ant profiler to hone unnecessary portions. Awesome tool!

I wanted to use a pool of pre-allocated byte arrays, but a managed DX assembly allocates byte buffers inside, and then returns this to the application. It turned out that I did not need it.

+2
Oct 18 '08 at 3:25
source share

You may have a limited number of instances of each type in the pool and reuse already done with instances. The size of the pool will depend on the number of messages that you will process.

+1
Sep 17 '08 at 17:02
source share

Instead of creating a new instance of the object each time you receive a message, why not reuse objects that have already been used? This way you won’t fight the garbage collector and your heap memory will not be fragmented. **

For each type of message, you can create a pool to store instances that are not in use. Whenever you receive a network message, you look at the type of message, pull the waiting instance from the corresponding pool, and apply your business logic. After that, you put this instance of the message object back into the pool.

Most likely, you will want to "lazily load" your pool using instances so that your code scales easily. Thus, your pool class will need to detect when the null instance has been pulled out and populate it before passing it. Then, when the call code puts it back into the pool, it is a real instance.

** "An object pool is a template that allows you to reuse objects rather than allocate and free them, which helps prevent heap fragmentation, as well as costly GC compaction."

http://geekswithblogs.net/robp/archive/2008/08/07/speedy-c-part-2-optimizing-memory-allocations---pooling-and.aspx

+1
Sep 17 '08 at 17:15
source share

Theoretically, the GC should not start if your processor is under heavy load or if it is really necessary. But if you need to, you can just keep all your objects in memory, perhaps one instance of one, and never clear them unless you are ready. This is probably the only way to guarantee when the GC is working.

0
Sep 17 '08 at 17:06
source share



All Articles