Groups | Blog | Home
all groups > dotnet performance > december 2003 >

dotnet performance : Thread (GCHeap::FinalizerThreadStart) takes a long time and a lot of CPU!


Adam
12/17/2003 12:55:31 AM
Hi

Our application has the following architecture : Rich Client (C#),
Business-Logic/Processing tier (C#, MC++) hosted in a Windows service
(stateful) and Data tier (custom 'DB' accessed via DCOM/COM written in
ATL/C++) (again stateful Windows Service). Client machines are P3 1Ghz
(512MB) or so and the servers are either single or dual P3 1.5Ghz XEONs
(1GB+).

I've been tracking a problem for a while now .... our client application can
spontaneously disconnect (sometimes badly) from its 'server' or the server
just slows down to treacle speed with plenty of CPU free but seemingly not
much going on. FYI: we use Genuine Channels to get between client and
business logic tiers (sometimes our clients connect via WAN through routers)
and it's call response timeouts are set quite high. However, even with high
timeout values we can still see issues and having looked at it in some
details today I see it's the Business Logic server causing the problems.

What happens is that the Windows service process on the BL server can go
100% intensive for a 'while' - anything from 30 seconds to a minute for
example, and this causes our client applications to lock, hang, disconnect
and/or generally misbehave! Looking at the process, I can see that the
thread with the following signature 'GCHeap::FinalizerThreadStart' is the
'culprit'. OK, this is the garbage collection thread which could indeed
(reading between the lines) cause my problem - it is documented on a single
CPU based system to suspend all threads, call finalize on all potential
candidates then release and allow the host process to continue on. On a
multi CPU system, it would run the GC on a single CPU whilst allowing the
server to run with diminished performance.

Objects are very transient within our system so there would be a lot of GC
activity once the user initiated tasks are complete! We make use of native
threads created on demand for executing a users request. Although we plan
significant improvement here by using a scheduler and thread pool, it's not
in the timeframe at the moment!

So, having described all of the above (hope it's clear enough!), is there
*anything* I can monitor, adjust, or consider to improve the situation? I
feel the GC is doing too much work all at once and once called, the
periodicity for being called again is quite a bit lower than the 1st time
(if that makes any sense!). Also is there anything in .NET which allows
notification (via Event or something) of when the GC is about to/is
running? - it be useful for diagnostic trace?

I'd really appreciate some good advice here please!
Thanks in advance!

Jon Skeet [C# MVP]
12/17/2003 9:17:28 AM
[quoted text, click to view]

Hang on - when you say it's "the garbage collection thread", I suspect
it's not - I suspect it's the finalization thread, which is somewhat
different. Are you letting a lot of IDisposable objects just get
garbage collected rather than disposing them? If so, that *might* be
the problem. Explicitly disposing things is a very good idea anyway.

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
Adam
12/19/2003 4:36:15 PM
Thx for the response.

I've not got too many IDisposeable objects so I cannot Dispose them myself.
I've changed the app so it will cache a group of objects instead of creating
new ones on demand. It less of a stateless design I was heading for in this
area but I'll monitor it to see how that change affects things.

[quoted text, click to view]

AddThis Social Bookmark Button