.Net CLR Test
The Common Language Runtime (CLR), the virtual machine component of Microsoft's .NET framework, manages the execution of .NET programs. A process known as just-in-time (JIT) compilation converts compiled code into machine instructions which the computer's CPU then executes. The CLR provides additional services including memory management, type safety, exception handling, garbage collection, security and thread management. All programs written for the .NET framework, regardless of programming language, are executed by the CLR.
This is why, if an application running on the .NET framework slows down, the first place that an administrator should look for hints is the CLR. Some of the common causes of poor program/application are excessive CLR heap usage, ineffective garbage collection by CLR, class loading failures, thread contentions on the CLR, and expensive run time checks by CLR. To be able to capture such anomalies on-the-fly, it is imperative that administrators closely monitor the performance of the CLR. The ASP .NET CLR test helps administrators do just that! The test auto-discovers the worker processes running in the ASP .NET server, and for every process, reports the following:
- The count of CLR exceptions that were thrown by that worker process;
- The heap memory usage of the worker process; in the event of excessive usage, you can also take a look at the garbage collection-related statistics reported by this test for that worker process to determine whether/not ineffective GC is causing heap memory usage to soar.
- The count of classes loaded and class loading failures;
- The rate of thread contentions in the worker process;
- The count of waiting threads;
- The time spent in performing runtime Code Access Security (CAS) checks;
- The count of runtime checks performed.
These metrics provide useful pointers to the source of performance degradations experienced by applications.
Target of the test : An IIS web server
Agent deploying the test : An internal agent;
Outputs of the test : One set of results for every worker process of every application pool on the monitored ASP .Net server
First-level descriptor: Application pool
Second-level descriptor: Worker process
|
Measurement | Description | Measurement Unit | Interpretation |
---|---|---|---|
Clr exceptions: |
The total number of managed exceptions thrown per second. |
Exceptions/Sec |
Exceptions are very costly and can severely degrade your application performance. A high value of this measure is therefore an indicator of potential performance issues. |
Heap mem usage |
The number of bytes committed by managed objects. This is the sum of the large object heap and the generation 0, 1, and 2 heaps. |
MB |
|
Gen 0 collections |
The number of generation 0 objects (youngest; most recently allocated) that were garbage collected (Gen 0 GC) since the start of the application. |
Number |
|
Gen 1 collections |
The number of generation 1 objects that were garbage collected since the start of the application. Objects that survive are promoted to generation 2. |
Number |
|
Gen 2 collections |
The number of times generation 2 objects have been garbage collected since the start of the application. |
Number |
Generation 2 is the highest, thus objects that survive collection remain in generation 2. Gen 2 collections can be very expensive, especially if the size of the Gen 2 heap is huge. |
Time in gc |
% Time in GC is the percentage of elapsed time that was spent in performing a garbage collection (GC) since the last GC cycle. |
Percent |
This measure is usually an indicator of the work done by the Garbage Collector on behalf of the application to collect and conserve memory. This measure is updated only at the end of every GC and the measure reflects the last observed value; its not an average. |
Classes loaded |
Indicates the cumulative number of classes loaded in all assemblies since the start of this worker process. |
Number |
A class is essentially the blueprint for an object. It contains the definition for how a particular object will be instantiated at runtime, such as the properties and methods that will be exposed publicly by the object and any internal storage structures.
|
Current classes loaded |
Indicates the current number of classes loaded in all Assemblies. |
Number |
An unusually high value may indicate a sudden increase in classes which loaded on to this .NET application. |
Rate of assemblies |
The rate at which Assemblies were loaded. |
Assembles/Sec |
Also known as Managed DLLs, assemblies are the fundamental unit of deployment for the .NET platform. The .NET Framework itself is made up of a number of assemblies, including mscorlib.dll, among others. The assembly boundary is also where versioning and security are applied. An assembly contains Intermediate Language generated by a specific language compiler, an assembly manifest (containing information about the assembly), type metadata, and resources. If the Assembly is loaded as domain-neutral from multiple AppDomains then this counter is incremented once only. Assemblies can be loaded as domain-neutral when their code can be shared by all AppDomains or they can be loaded as domain-specific when their code is private to the AppDomain. 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. |
Rate of classes loaded |
This rate at which the classes loaded in all Assemblies. |
Classes/Sec |
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. |
Rate of load failures |
The rate of load failures on this worker process. |
Failures/Sec |
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. These load failures could be due to many reasons like inadequate security or illegal format. |
Current appdomains |
The number of AppDomains currently loaded in this worker process. |
Number |
AppDomains (application domains) provide a secure and versatile unit of processing that the CLR can use to provide isolation between applications running in the same process. |
Current assemblies |
The number of assemblies currently loaded on this worker process. |
Number |
If the Assembly is loaded as domain-neutral from multiple AppDomains then this counter is incremented once only. Assemblies can be loaded as domain-neutral when their code can be shared by all AppDomains or they can be loaded as domain-specific when their code is private to the AppDomain. |
Loader heap size |
The size of the memory committed by the class loader. |
MB |
Committed memory is the physical memory for which space has been reserved on the disk paging file. |
Load failures |
The number of classes that have failed to load during the last measurement period. |
Number |
These load failures could be due to many reasons like inadequate security or illegal format. |
Appdomains loaded |
The number of AppDomains loaded during the last measurement period. |
Number |
|
Num assemblies |
The number of assemblies loaded during the last measurement period. |
Number |
An assembly in ASP.NET is a collection of single-file or multiple files. The assembly that has more than one file contains either a dynamic link library (DLL) or an EXE file. The assembly also contains metadata that is known as assembly manifest. The assembly manifest contains data about the versioning requirements of the assembly, author name of the assembly, the security requirements that the assembly requires to run, and the various files that form part of the assembly. The biggest advantage of using ASP.NET Assemblies is that developers can create applications without interfering with other applications on the system. |
Current logical threads |
The number of current managed thread objects in this worker process. This measure maintains the count of both running and stopped threads. |
Number |
|
Current physical threads |
The number of native operating system threads created and owned by the common language runtime to act as underlying threads for managed thread objects. This measure does not include the threads used by the runtime in its internal operations. |
Number |
|
Current recognized threads |
The number of threads that are currently recognized by the runtime. These threads are associated with a corresponding managed thread object. |
Number |
|
Contention rate |
The rate at which threads in the runtime attempt to acquire a managed lock unsuccessfully. |
Rate/Sec |
|
Current queue length |
The total number of threads that are currently waiting to acquire a managed lock in the application. |
Number |
|
Queue length rate |
Indicates the rate at which threads are waiting to acquire some lock. |
Threads/Sec |
|
Recognized threads rate |
Indicates the number of threads per second that have been recognized by the CLR. |
Threads/Sec |
The recognized threads 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 the same thread ID re-entering the CLR or recreated after thread exit are not counted twice. |
Queue length peak |
Indicates the total number of threads that waited to acquire some managed lock during the last measurement period. |
Number |
A high turnover rate indicates that items are being quickly added and removed, which can be expensive. |
Recognized threads |
Indicates the total number of threads that have been recognized by the CLR during the last measurement period. |
Number |
The recognized threads 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 the same thread ID re-entering the CLR or recreated after thread exit are not counted twice. |
Contention threads |
Indicates the total number of times threads in the CLR have attempted to acquire a managed lock unsuccessfully. |
Number |
Managed locks can be acquired in many ways; by the lock statement in C# or by calling System.Monitor.Enter or by using MethodImplOptions.Synchronized custom attribute. |
Time in runtime checks |
Indicates the percentage of elapsed time spent in performing runtime Code Access Security (CAS) checks during the last measurement period. |
Percent |
If this counter is high, revisit what is being checked and how often. The application may be executing unnecessary stack walk depths. Another cause for a high percentage of time spent in runtime checks could be numerous linktime checks. |
Stack walk depth |
Indicates the depth of the stack during that last measurement period. |
Number |
|
Link time checks |
Indicates the total number of linktime Code Access Security (CAS) checks during the last measurement period. |
Number |
The value displayed is not indicative of serious performance issues, but it is indicative of the health of the security system activity. |
Runtime checks |
Indicates the total number of runtime CAS checks performed during the last measurement period. |
Number |
A high number for the total runtime checks along with a high stack walk depth indicates performance overhead. |