New Performance Counter Features [Ryan Byington]

Introduction
Before going into detail of the changes in v2.0 I think it is important to start off with explaining the existing problems with the performance counter infrastructure. The first problem is the memory reserved for performance counters is fixed, though the initial size of the memory can be changed from a config file. By itself this is not all that bad however combined with the following problems makes this a pretty big limitation.

The second problem is that we don’t do a good job or reusing the data in memory. You might think that every time you remove an instance from you counter that this data will actually get reused by the next instance created on your category but this is simply not the case. We will only reuse the data from a removed instance if an instance with the exact same name is created.

The final problem is that all categories created through the PerformanceCounterCategory API’s share the same memory on the machine. This means if some other category is being written to in some other process and possibly in some other version of the .Net Framework and fills up the performance counter memory that you will not be able to write to your counters. 

All of this put together is pretty bad. You can only create a limited number of counters/instances on your category but this number in not deterministic since it is dependent on what memory was leaked and the other processes on the machine writing to performance counters. Plus you may not even be able to write to one counter/instance if some other poorly written app already used up all of the memory.

Changes in V2.0
The first problem has not been fixed. However we feel that this problem has been mitigated by the other changes that we have made in V2.0. Sure you can not have an unlimited number of instances on you category but I doubt there is really any Category that needs this. Usually an instance corresponds to a Process/Thread/AppDomian or some other resource and realistically a machine can only handle so many of these resources.

Now you are probably wondering what did we do to solve the other problems. Each category created in V2.0 will now have it’s own memory. Also with these categories we can reuse all of the data used by an instance after if has been removed. With these changes the number of active instances(instances currently being written to) is finally deterministic and the data from other categories can not affect your category. The behavior of categories created in V1.0 or V1.1 do not change in V2.0.

Performance Counter Side by Side Issues
However v1.0 and v1.1 do not know about categories that use their own memory and consequently we broke backward compatibility with these versions. V1.0 and V1.1 will still be able to read your V2.0 category but by default they will not be able to write to a V2.0 category.

Although by setting a registry value all versions of the .Net Framework can write to the same category. However this category will use the same memory that is shared between other V1.0 and V1.1 categories and data from instances will not always be reused and will thus have the problems mentioned above. This behavior controlled by the CategoryOptions value in HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\<YOUR CATEGORY NAME>\Performance registry key. CategoryOptions can have the following values:

0 This is the behavior if the CategoryOptions value is not present. V2.0 will have the same behavior as V1.1 and V1.0. The category will share the memory with other categories with this value. Instance data will only be reused if name of the instance being created is exactly the same as the instance being reused. All versions will be able to write to the category.

1 Same as above except the data for instances will be reused if the name of the instance being created is the same length as the name of the instance being reused.

3 Default for categories created in V2.0. Category uses it’s own memory. All instance data can be reused. V1.1 V1.0 can read data form this category but can not write to it.