5 Microsoft .NET Framework Metrics

This chapter provides descriptions for all Microsoft .NET Framework metric categories, and tables list and describe associated metrics for each category. The tables also provide user actions if any of the metrics for a particular category support user actions.

.NET CLR Exceptions Metrics

The metrics in the .NET CLR Exceptions category provide information about the exceptions thrown by an application.

Default Collection Interval — Every 15 minutes

Table 5-1 .NET CLR Exceptions Metrics

Metric Description and User Action

Exceptions Thrown

This counter indicates the total number of exceptions generated in managed code since the application restarted.

Exceptions are very costly and can severely degrade your application performance. You should investigate your code for application logic that uses exceptions for normal processing behavior. Response.Redirect, Server.Transfer, and Response.End all cause a ThreadAbortException in ASP.NET applications. This counter value should be less than 5 percent of Request/sec for the ASP.NET application. If more than 1 request in 20 throw an exception, be attentive to these occurrences.

Exceptions Thrown Per Sec

This counter indicates the total number of exceptions generated per second in managed code.

Exceptions are very costly and can severely degrade your application performance. You should investigate your code for application logic that uses exceptions for normal processing behavior. Response.Redirect, Server.Transfer, and Response.End all cause a ThreadAbortException in ASP.NET applications. This counter value should be less than 5 percent of Request/sec for the ASP.NET application. If more than 1 request in 20 throw an exception, be attentive to these occurrences.

Exceptions Thrown Since Last Upload

Displays the total number of exceptions thrown during the last metric collection.

Exceptions are very costly and can severely degrade your application performance. You should investigate your code for application logic that uses exceptions for normal processing behavior. Response.Redirect, Server.Transfer, and Response.End all cause a Thread Abort Exception in ASP.NET applications. This counter value should be less than 5 percent of Request/sec for the ASP.NET application. If more than 1 request in 20 throw an exception, be attentive to these occurrences.


.NET CLR Interop Metrics

The metrics in the .NET CLR Interop category provide information about an application's interaction with COM components, COM+ services, and external type libraries.

Default Collection Interval — Every 15 minutes

Table 5-2 .NET CLR Interop Metrics

Metric Description and User Action

CCWs

Displays the current number of COM callable wrappers (CCWs). A CCW is a proxy for a managed object being referenced from an unmanaged COM client. This counter indicates the number of managed objects referenced by unmanaged COM code.

This value must be as low as possible. If this number is high, determine whether you can redesign this part of the application to reduce the number of transitions needed. If you see memory expanding (or not becoming freed when it should have been) and this counter is increasing, this may suggest that unmanaged code is holding on to some of your managed objects, thereby causing memory either not being freed or increasing.

Marshalling

Displays the total number of times arguments and return values have been marshalled from managed to unmanaged code, and vice versa, since the application started.

This value must be as low as possible. If this number is high, determine whether you can redesign this part of the application to reduce the number of transitions needed.

Stubs

Displays the current number of stubs created by the common language runtime. Stubs are responsible for marshaling arguments and return values from managed to unmanaged code, and vice versa, during a COM interop call or a platform invoke call.

This value must be as low as possible. For calls being made from managed and unmanaged code and vice-versa, this counter indicates the interaction between COM and managed code. If this number is high, determine whether you can redesign this part of the application to reduce the number of needed transitions.


.NET CLR JIT Metrics

The metrics in the .NET CLR Jit category provide information about Just-in-Time (JIT) information for the code that has just been compiled. JIT compilation is used to compile IL methods to native machine language immediately before execution of the methods.

Default Collection Interval — Every 15 minutes

Table 5-3 .NET CLR JIT Metrics

Metric Description and User Action

IL Bytes Jitted

Displays the total number of Microsoft Intermediate Language (MSIL) bytes compiled by the Just-in-Time (JIT) compiler since the application started.

A high value for this performance counter indicates performance overhead. The JIT is a runtime optimizing compiler. You can consider improving the startup time of client applications by compiling your application at install time, using the NGEN.exe utility.

Methods Jitted

Displays the total number of methods JIT-compiled since the application started. This counter does not include pre-JIT-compiled methods.

A high value for this performance counter indicates performance overhead. The JIT is a runtime optimizing compiler. You can consider improving the startup time of client applications by compiling your application at install time, using the NGEN.exe utility.

Standard Jit Failures

Displays the peak number of methods the JIT compiler has failed to compile since the application started.

A high value for this counter indicates a problem with the JIT compiler. This failure can occur if the IL cannot be verified, or if there was an internal error in the JIT compiler. Check the .NET framework setup to troubleshoot.


.NET CLR Loading Metrics

The metrics in the .NET CLR Loading category provide information assemblies, classes, and application domains that are loaded.

Default Collection Interval — Every 15 minutes

Table 5-4 .NET CLR Loading Metrics

Metric Description and User Action

Load Failures

Displays the peak number of classes that have failed to load since the application started.

Load failures can occur for many reasons, such as inadequate security or invalid format. Check your code to fix the problem.

Application Domains Loaded Since Last Upload

Displays the number of application domains loaded in this application during the last metric collection.

Often, especially for security reasons, you cannot avoid using multiple AppDomains. However, doing so can limit performance at startup. You can reduce the impact of multiple App Domains by loading assemblies as domain neutral, enforcing efficient cross-AppDomain communication, using NeutralResourcesLanguageAttribute, and using serialization wisely.

Application Domains Unloaded Since Last Upload

Displays the number of application domains unloaded in this application during the last metric collection.

Often, especially for security reasons, you cannot avoid using multiple AppDomains. However, doing so can limit performance at startup. You can reduce the impact of multiple App Domains by loading assemblies as domain neutral, enforcing efficient cross-AppDomain communication, using NeutralResourcesLanguageAttribute, and using serialization wisely.

Bytes in Loader Heap

Indicates the current size (in bytes) of committed memory by the class loader across all AppDomain(s). Committed memory is the physical memory for which space has been reserved in the paging file on disk.

This counter must be in a steady state; otherwise, large fluctuations in this counter indicate there are too many assemblies loaded per AppDomain. Change the page file size accordingly to improve performance.

Current Application Domains

Displays the current number of application domains loaded in this application.

The value should be same as the number of Web applications plus one. The additional application is the default application domain loaded by the ASP.NET worker process. Often, especially for security reasons, you cannot avoid using multiple AppDomains. However, doing so can limit performance at startup. You can reduce the impact of multiple App Domains by loading assemblies as domain neutral, enforcing efficient cross-AppDomain communication, using NeutralResourcesLanguageAttribute, and using serialization wisely.

Current Assemblies

Displays the current number of assemblies loaded across all application domains in the currently running application. It includes the Application Domains in the system. ASP.NET Web pages (.aspx files) and user controls (.ascx files) are "batch compiled" by default, which typically results in one to three assemblies, depending on the number of dependencies. An unusually high number of loaded assemblies can cause excessive memory consumption.

Try to minimize the number of Web pages and user controls without compromising the efficiency of workflow. Assemblies cannot be unloaded from an application domain. To prevent excessive memory consumption, the application domain is unloaded when the number of recompilations (.aspx, .ascx, .asax) exceed the limit specified by <compilation numRecompilesBeforeAppRestart=/>.

Note: If the <%@ page debug=%> attribute is set to true, or if <compilation debug=/> is set to true, batch compilation is disabled.

Current Classes Loaded

Displays the current number of classes loaded in all assemblies.

If this value is too high, consider increasing the physical memory to improve performance.

Load Failures Since Last Upload

Displays the peak number of classes that have failed to load during the last metric collection.

Load failures can occur for many reasons, such as inadequate security or invalid format. Check your code to fix the problem.

Time Loading Percent

Reserved for future use.

Total Application Domains

Displays the peak number of application domains loaded since the application started.

Often, especially for security reasons, you cannot avoid using multiple AppDomains. However, doing so can limit performance at startup. You can reduce the impact of multiple AppDomains by loading assemblies as domain neutral, enforcing efficient cross-AppDomain communication, using NeutralResourcesLanguageAttribute, and using serialization wisely.

Total Application Domains Unloaded

Displays the peak number of application domains unloaded since the application started.

Often, especially for security reasons, you cannot avoid using multiple AppDomains. However, doing so can limit performance at startup. You can reduce the impact of multiple App Domains by loading assemblies as domain neutral, enforcing efficient cross-AppDomain communication, using NeutralResourcesLanguageAttribute, and using serialization wisely.

Total Assemblies

Displays the total number of assemblies loaded since the application started.

Try to minimize the number of Web pages and user controls without compromising the efficiency of workflow. Assemblies cannot be unloaded from an application domain. To prevent excessive memory consumption, the application domain is unloaded when the number of recompilations (.aspx, .ascx, .asax) exceed the limit specified by <compilation numRecompilesBeforeAppRestart=/>.

Note: If the <%@ page debug=%> attribute is set to true, or if <compilation debug=/> is set to true, batch compilation is disabled.

Total Classes Loaded

Displays the cumulative number of classes loaded in all assemblies since the application started.


.NET CLR Locks and Threads Metrics

The metrics in the .NET CLR Locks and Threads category provide information about managed locks and threads that an application uses.

Default Collection Interval — Every 15 minutes

Table 5-5 .NET CLR Locks and Threads Metrics

Metric Description and User Action

Contention Rate Per Sec

Displays the rate at which threads in the runtime unsuccessfully attempt to acquire a managed lock.

Sustained nonzero values should cause concern. If this number is increasing, a bottleneck exists in the code. This area in the code is synchronized, so only one thread at a time enters it, but it is being "hammered" by multiple threads that are all attempting to get into this piece of code. To resolve this bottleneck, find this piece of code and determine how you can avoid this situation.

Contentions Since Last Upload

Displays the total number of times that threads in the runtime have attempted to acquire a managed lock unsuccessfully during the last metric collection.

Sustained nonzero values should cause concern. If this number is increasing, a bottleneck exists in the code. This area in the code is synchronized, so only one thread at a time enters it, but it is being "hammered" by multiple threads that are all attempting to get into this piece of code. To resolve this bottleneck, find this piece of code and determine how you can avoid this situation.

Current Logical Threads

Displays the number of current managed thread objects in the application. This counter is not an average over time; it just displays the last observed value.

This counter maintains the count of both running and stopped threads. A value that is too high may be a cause of concern.

Current Physical Threads

Displays the number of native operating system threads created and owned by the common language runtime to act as underlying threads for managed thread objects.

A value that is too high indicates performance bottlenecks. If this value is too high, try to refactor the code to reduce the number of spawned threads to an optimal value.

Current Queue Length

Displays the total number of threads that are currently waiting to acquire a managed lock in the application.

You may want to run dedicated tests for a particular piece of code to identify the average queue length for the particular code path. This helps you identify inefficient synchronization mechanisms.

Current Recognized Threads

Displays the number of threads that are currently recognized by the runtime; they have a corresponding .NET thread object associated with them. These threads are not created by the CLR. They are created outside the CLR, but have since run inside the CLR at least once. Only unique threads are tracked. Threads with same thread ID re-entering the CLR or recreated after thread exit are not counted twice.

Queue Length Peak

Displays the total number of threads that waited to acquire a managed lock since the application started.

You may want to run dedicated tests for a particular piece of code to identify the average queue length for the particular code path. This helps you identify inefficient synchronization mechanisms.

Queue Length Per Sec

Displays the number of threads per second that are waiting to acquire a lock in the application.

You may want to run dedicated tests for a particular piece of code to identify the average queue length for the particular code path. This helps you identify inefficient synchronization mechanisms.

Total Contentions

Displays the total number of times that threads in the runtime have attempted to acquire a managed lock successfully.

Sustained nonzero values may be a cause of concern. You may want to run dedicated tests for a particular piece of code to identify the contention rate for the particular code path.

Total Recognized Threads

Displays the total number of threads that have been recognized by the runtime since the application started.


.NET CLR Memory Metrics

The metrics in the .NET CLR Memory category provide information about managed and unmanaged memory consumption.

Default Collection Interval — Every 15 minutes

Table 5-6 .NET CLR Memory Metrics

Metric Description and User Action

Bytes in All Heaps

Displays the current memory allocated in bytes on the garbage collection heaps. This counter is the sum of four other counters — Gen 0 Heap Size, Gen 1 Heap Size, Gen 2 Heap Size, and Large Object Heap Size. The value of this counter is always less than the value of Process/Private Bytes, which also includes the native memory allocated for the process by the operating system. Private Bytes - # Bytes in all Heaps is the number of bytes allocated for unmanaged objects.

If this counter continues to rise, there is a managed leak. Some managed objects are always being referenced and are never collected.

Pinned Objects

When .NET-based applications use unmanaged code, these objects are pinned in memory. That is, they cannot move around because the pointers to them would become invalid. These can be measured by this counter, which displays the number of pinned objects encountered in the last garbage collection.

Too many pinned objects affect the performance of the garbage collector, because they restrict its ability to move objects and organize memory efficiently. You can also pin objects explicitly in managed code, such as reusable buffers used for I/O calls. Try to reduce the number of pinned objects in the code.

Generally, this number shouldn't be too high if you don't call to unmanaged code too often. If this counter is increasing, it might suggest that you are pinning objects due to passing them into unmanaged code and not releasing the unmanaged code, or you explicitly pinned objects and forgot to unpin them.

If this counter is increasing and the Virtual Bytes counter is also increasing, pin objects are being done too often and the GC cannot effectively compact the heap. This forces the heap to reserve additional virtual memory so the GC heap can expand and accommodate the requested needs of allocation.

Sink Blocks in Use

Displays the current number of synchronization blocks in use. Synchronization blocks are per-object data structures allocated for storing synchronization information. Synchronization blocks hold weak references to managed objects and must be scanned by the garbage collector. Synchronization blocks are not limited to storing synchronization information; they can also store COM interop metadata.

This counter indicates performance problems with heavy use of synchronization primitives. If this counter continues to increase, examine all the locations where you are using synchronization objects and determine if they are really needed.

Time in Garbage Collection Percent

Displays the percentage of elapsed time that was spent performing a garbage collection since the last garbage collection cycle.

This counter should average about 5 percent for most applications when the CPU is 70 percent busy, with occasional peaks. As the CPU load increases, so does the percentage of time spent performing garbage collection. Keep this in mind when you measure the CPU. The most common cause of a high value is making too many allocations, which may be the case if you are allocating on a per-request basis for ASP.NET applications. Study the allocation profile for your application if this counter shows a higher value.


.NET CLR Networking Metrics

The metrics in the .NET CLR Networking category provide information about data that an application sends and receives over the network.

Default Collection Interval — Every 15 minutes

Table 5-7 .NET CLR Networking Metrics

Metric Description and User Action

Bytes Received

Displays the cumulative number of bytes received over all open socket connections. This number includes data and any protocol information that is not defined by TCP/IP.

When tuning the network utilization of an application, this counter indicates the total traffic generated by all .NET-based applications. Note that these counters do not let you monitor a specific .NET-based application. However, they do not measure network traffic that is generated by applications that do not use the common language runtime.

Bytes Sent

Displays the cumulative number of bytes sent over all open socket connections since the process started. This number includes data and any protocol information that is not defined by TCP/IP.

When tuning the network utilization of an application, this counter indicates the total traffic generated by all .NET-based applications. Note that these counters do not let you monitor a specific .NET-based application. However, they do not measure network traffic that is generated by applications that do not use the common language runtime.

Connections Established

Displays the cumulative number of socket connections established for this process since it started. A high value for this counter indicates a large number of users trying to use the application, which equates to high usage for the application.

Connection Established Since Last Upload

Displays the number of socket connections established for this process during the last metric collection. A high value for this counter indicates a large number of users trying to use the application, which equates to high usage for the application.

Datagrams Received

Displays the cumulative number of datagram packets received since the process started. When tuning the network utilization of an application, this counter indicates the datagram packets traffic received by all .NET-based applications.

Datagrams Sent

Displays the cumulative number of datagram packets sent since the process started. When tuning the network utilization of an application, this counter indicates the datagram packets traffic sent by all .NET-based applications.


.NET CLR Remoting Metrics

The metrics in the .NET CLR Remoting category provide information about .NET remoting performance and its various key performance counters. The throughput of the remote component can be measured using the Remote Calls Per Sec and Requests Per Sec counters.

Default Collection Interval — Every 15 minutes

Table 5-8 .NET CLR Remoting Metrics

Metric Description and User Action

Channels

Displays the total number of remoting channels registered across all application domains since the application started. Channels transport messages to and from remote objects.

Use TcpChannel for optimum performance. Use the TcpChannel in trusted server scenarios.

Context Bound Classes Loaded

Displays the current number of context-bound classes that are loaded. Classes that can be bound to a context are called context-bound classes. These classes are marked with context attributes, which provide usage rules for synchronization, thread affinity, transactions, and so forth.

Context Bound Objects Alloc Per Sec

Displays the number of context-bound objects allocated per second. Classes that can be bound to a context are called context-bound objects. These classes are marked with context attributes, which provide usage rules for synchronization, thread affinity, transactions, and so forth.

This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval.

Context Proxies

Displays the total number of remoting proxy objects in this process since it started. A proxy object acts as a representative of the remote objects and ensures that all calls made on the proxy are forwarded to the correct remote object.

Contexts

Displays the current number of remoting contexts in the application. A context is a boundary containing a collection of objects with the same usage rules such as synchronization, thread affinity, transactions, and so forth.

Remote Calls Per Sec

Displays the number of remote procedure calls invoked per second. A remote procedure call is a call on any object outside the caller's application domain. This counter is not an average over time; it displays the difference between the values observed in the last two samples divided by the duration of the sample interval.

More than one remote call may be required to complete a single operation. You need to divide the counter with the amount of requests to complete a single operation. This gives you the rate of operations completed per second. You might need to instrument your code to observe the request execution time.

Total Remote Calls

Displays the total number of remote procedure calls invoked since the application started.

More than one remote call may be required to complete a single operation. You need to divide the counter with the amount of requests to complete a single operation. This gives you the rate of operations completed per second. You might need to instrument your code to observe the request execution time.


.NET CLR Security Metrics

The metrics in the .NET CLR Security category provide information about code access security checks and how they affect performance.

Default Collection Interval — Every 15 minutes

Table 5-9 .NET CLR Security Metrics

Metric Description and User Action

Link Time Checks

Displays the total number of link-time code access security checks since the application started.

Percent Time In RT Checks

Displays the percentage of elapsed time spent performing runtime code access security checks since the last sample.

Percent Time Sig Authenticating

Reserved for future use.

Stack Walk Depth

Displays the depth of the stack during the last runtime code access security check. This counter is not an average. It just displays the last observed value.

Total Runtime Checks

Displays the total number of runtime code access security checks performed since the application started. When used together with the Stack Walk Depth counter, this counter indicates the performance penalty that your code incurs for security checks.


.NET Data Metrics

The metrics in the .NET Data category provide information about ADO.NET data access performance. These counters provide valuable information to effectively measure the data access performance by measuring the utilization and effectiveness of pooling and failed connects.

Default Collection Interval — Every 15 minutes

Table 5-10 .NET Data Metrics

Metric Description and User Action

SQL Client Current Pooled and Non-Pooled Connections

Current number of connections, pooled or not. A very high value for this counter indicates unclosed connections in the application.

Try closing all the connections when you are finished with them.

SQL Client Failed Commands

Total number of command executions that have failed for any reason. A high value for this counter is a cause of concern.

Try examining the problem in the code to see if there are any setup issues.

SQL Client Failed Connects

Total number of connection open attempts that have failed for any reason. A high value for this counter is a cause of concern.

Try examining the problem in the code to see if there are any setup issues.


NetCLR Response Metrics

The metric in the NetCLR Response category provides information about the status of the Microsoft .NET Framework.

Default Collection Interval — Every minute

Table 5-11 NetCLR Response Metrics

Metric Description and User Action

Status

Displays the status of the Microsoft IIS 6.0 target. The status of the target is based on whether the service IISADMIN is running or stopped.

If the status is shown as down, check whether the Microsoft IISADMIN service is running. If the status of the target is not shown properly, check whether the Agent is reachable or not.