Difference Between Perf Data Reported by Different Tools – 3


Both the !SOS.gchandles command (added in CLR 2.0) and the .NET CLR Memory\# GC Handles counter show you the number of GC handles you have in your process.


The # GC Handles counter is one of the rare counters in the .NET CLR Memory category that doesn’t get updated at the end of each GC. Rather we update it in the handle table code, for example, when some code in the CLR calls the function to create a GC handle (possibly because the user has requested to create a handle via managed code), we increase this counter value by one. For performance reasons we don’t use interlocked operations when we need to increase or decrease this value. This means the value can get changed concurrently by multiple threads. For this reason you should always trust the value returned by the !SOS.gchandles command if you ever doubt the counter value. The SOS command is accurate because we always walk the handle table when you issue the command so it returns the # of handles truthfully.

Comments (15)

  1. Eric Wilson says:

    If the #GC Handles counter isn’t REALLY the number of handles outstanding, what good is this perf counter?

  2. maoni says:

    Performance doesn’t need to be 100% accurate all the time – it all depends on what you need to accomplish. In this case you can use the counter as an estimation so you have an idea approx. how many handles you have. For example, if the value goes really high then you may want to try the other more accurate but more costly method like the sos command.

  3. Sam Gentile says:

    A special Christmas Eve version to clean out my Feed Demon box as I will be on vacation next week and

  4. Kannan says:

    We have a setup in our production server where there are several application pools (about 5 to 6 in no.).

    We have set up perf. mon to collect data on the worker process instances(w3wp, w3wp#1 etc).

    When collecting this info’, we often come across this situation where after the server is reset by one of our monitoring tools (sitescope), the worker process on which we have been collecting data for a certain application pool seems to get reassigned to a different application pool.

    Since perf. data is collected based on the name of the process, we are finding it difficult to associate a worker process with the corresponding application pool. How do we ensure that the perf. data for a worker process is always collected for a specific application pool ?

  5. maoni says:

    Kannan, there are various ways. If you are interested in the CLR counters, there’s a .NET CLR MemoryProcess ID which you can use to associate the counters with the process they are from.

  6. Kannan says:

    Maoni, thanks for replying. I was able to append process ids to the worker process instances by using the below registry key

    HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesPerfProcPerformance

    and setting it to 2

    I was looking for this in the counters list and I was confused because none of the CLR counters have a Process ID in the counters list.

    However, this setting means that after every recycle we will see different set of process ids for each w3wps and we will have new set of columns in the perf. counters.

  7. Ed Klos says:

    The .NET CLR MemoryProcess ID counter doesn’t seem to be available on W2K3 Server.  I see this counter on my WinXP box (I have .NET 1.1 and 2.0 installed as well as all of the latest service patches).  However, on an XP box with just 1.1 installed, this metric is not there.

    So I have two questions: (1) how does this metric become available via which framework/service level; and (2) is this metric available on W2K3 and W2K?

  8. maoni says:

    Ed, the process id counter was added in .NET 2.0 so if you have it installed you should have it whether you are on w2k, 2k3 or xp.

  9. Ed Klos says:

    Thanks for the quick reply…

    The problem I am seeing is this, if I have .NET 1.1 installed prior to .NET 2.0, then I do not see this new counter (.NET CLR MemoryProcess ID), however, if I uninstall .NET 1.1 and then reinstall .NET 2.0 then the counter appears!  Is there a problem with the MOF registration if .NET 1.1 is installed first?

    Now on W2K3, .NET 1.1 comes pre-installed and you cannot uninstall it (since it is packaged as part of the OS).  If my assumptions are correct (MOF registration issue), then how can I rebuild the MOF repository in such a way that it excludes .NET 1.1 or uses the .NET 2.0 definitions?

    Once again, thanks for your help…

  10. maoni says:

    Ed, yeah, there’s a problem with the setup for the perf counters ’cause it’s missing a step to unload the counters before installing new ones. You can fix this by doing the following:

    unlodctr .NETFramework

    lodctr corperfmonsymbols.ini_for_2.0

    the corperfmonsymbols.ini_for_2.0 should be in your .NET 2.0 directory.

  11. Ed Klos says:

    Thanks Maoni – that works!

  12. Is there still a defect in the perfmon counters with .Net 2.0.

    We are seeing 200K+ GC Handles on production servers, but taking a hang dump and using sos’ !gchandles only shows 400.

  13. maoni says:

    The drifting problem I described is not fixed in 2.0.

    When in doubt, trust the output from !sos.gchandles.

  14. bh says:

    Hello Maoni: Thanks for all this information.

    a) Where do I find this !SOS.gchandles command

    b) How do I execute it? Do I run some program first and then enter this command?

    c) etc.

    please clue me in. Thanks.

  15. A special Christmas Eve version to clean out my Feed Demon box as I will be on vacation next week and then in Belgium for a week after that so don't expect much if any blogging. CLR Modeling servers for resource consumption Windows keyed events, critical