views:

237

answers:

2

I have a C# windows service acting as a server, the service holds some large (>8Gb) data structures in memory and exposes search methods to clients via remoting.

The avg search operation is executed in <200ms and the service handles up to 20 request/sec.

I'm noticing some serious performance degradation (>6000ms) on a regular basis for few seconds

My best guess is that the server threads are stopped by a gen2 garbage collection from time to time.

I'm considering switching from server gc to workstation gc and wrap my search method in this to prevent GC during requests.

 static protected void DoLowLatencyAction(Action action)
    {
        GCLatencyMode oldMode = GCSettings.LatencyMode;
        try
        {
            GCSettings.LatencyMode = GCLatencyMode.LowLatency;
            // perform time-sensitive actions here
            action();
        }
        finally
        {
            GCSettings.LatencyMode = oldMode;
        }
    }

Is this a good idea?

Under what conditions the GC will be performed anyway inside the low latency block?

Note: I'm running on a x64 server with 8 cores

Thanks

+4  A: 

I've not used GCLatencyMode before so cannot comment on whether using it is a good idea or not.

However, are you sure you are using server GC? By default, Windows services use workstation GC.

I've had a similar problem before in a Windows service, and setting server GC mode using:

<configuration>
    <runtime>
        <gcServer enabled="true" />
    </runtime>
</configuration>

in the service's app.config file solved it.

Have a read of this post from Tess Ferrandez's blog for a more details.

adrianbanks
That link to the post is a great resource, thanks.
280Z28
+1 for the link
Luca Martinetti
A: 

I am surprised that your search method even trigger a GC, if the 8GB datastructure is static ( not modified a lot by adding or removing from it ), and all you do is searching it, then you should just try to avoid allocating temporary objects within your search method ( if you can ). Creating objects is the thing that triggers a GC, and if you have a data structure that is rarely modified, then it makes sense to avoid the GC all together ( or delay it as much as possible ).

GCSettings.LowLatency does is it gives a hint to the GC to do eager collections such that we can avoid Gen2 collections while the LowLatency mode is set. What this does as a side effect is make the GC eager to collect outside the region where LowLatency mode is set, and could result in lower performance ( in this case you can try server GC mode ).

mfawzymkh