We have a .Net windows service running on a Windows 2003 64-bit machine whose main purpose is to cache Gigabytes worth of data and make that data available via remoting calls. Currently, the process uses 13.6 gigabytes worth of memory, storing data in three main Hashtables. The problem we're experiencing involves garbage collection. At 13.6 GB, the garbage collector seems to run about every two minutes, halting program execution for 30 seconds each time. This is a big problem due to the fact that we are going to have many client applications requesting data from this service at random times and we cannot have them time out due to the garbage collection process. So my question is, is there a way to control garbage collection in this scenario to avoid these 30 second blackouts

Controlling Garbage Collection?
Ray1127
Mohammad,
Unfortunately I don't recommend your KeepAlive suggestion, at least not until the application has been profiled and the source of the problem has been traced back to large hashtables being collected. If they are being collected, then I would recommend my previous suggestion of re-using large objects instead of letting them die and allocating new ones.
As for your GC.Collect suggestion, one must be very careful to implement any solution that relies on calling GC.Collect manually. Rico Mariani has a great blog post about when it is appropriate to call GC.Collect: http://blogs.msdn.com/ricom/archive/2004/11/29/271829.aspx
One of the most common mistakes is trying to get the GC to behave differently before profiling the application and determining where the problem actually is.
Hope that helps!
-Chris
Mike Diaz
There is no way to directly control the GC (as in suspend collections for an amount of time). Instead, I would suggest taking the following steps to improve performance:
-Use Server GC instead of Workstation. This should decrease "blackout" time and improve throughput (only available on multi-proc machines).
-Using short-lived large objects will result in poor performance. Consider implementing a "large object pool" to resuse objects instead of allocating new ones. This is because the large object heap is expensive to collect, and you can minimize collections by limiting the number of allocations.
-Use the CLRProfiler to determine what objects are alive at any given time, and where the GC is spending its time.
Let me know if these solutions help at all.
-Chris
jackycn
If you are sure that the size data in your hash tables will not exceed a certain limit, you can stop the garbage collector from collecting them by calling GC.KeepAlive(), but I don't recommend this scenario.
I suggest that you force garbage collection in the times in which your system is idle, by calling GC.Collect(). you can even specify collection of old generation memory only to decrease the garbage collection time. in this way, automatic garbage collection will not be triggered very often, and even when it is triggered, it will not take a lot of time.
hpassant
Thanks for the link Chris.It is very interesting.
But I have noted that some comments on this blog reported that in some situations, calling GC.Collect() regularly increased the performance dramatically. As you said, this needs profiling first.
Also I would like to ask about the number of processors on the server. If the server is a multi processor one, then the GC would run in a separate thread on one of the processors, and this doesn't stop the response of the system when the GC is running.
Another point, I think 13 GB of data is very big to allocate in the memory. I think using a database to cash the data would be better, while using smaller hash tables as some sort of L1 Cache.