Return to HomePage



How To: Tune the .NET Framework


Source: http://msdn.microsoft.com/library/en-us/dnpag/html/scalenetchapt17.asp
J.D. Meier, Srinath Vasireddy, Ashish Babbar, Rico Mariani, and Alex Mackman


To tune the .NET Framework, you need to tune the CLR. Tuning the CLR affects all managed code, regardless of the implementation technology. You then tune the relevant .NET Framework technology, depending on the nature of your application. For example, tuning the relevant technology might include tuning ASP.NET applications or Web services, Enterprise Services, and ADO.NET code.
CLR Tuning
CLR tuning is mostly achieved by designing and then optimizing your code to enable the CLR to perform its tasks efficiently. Your design needs to enable efficient garbage collection, for example by correctly using the Dispose pattern and considering object lifetime.
The main CLR-related bottlenecks are caused by contention for resources, inefficient resource cleanup, misuse of the thread pool, and resource leaks. For more information about optimizing your code for efficient CLR processing, see Chapter 5, "Improving Managed Code Performance."
Metrics
Use the performance counters shown in Table 17.5 to help identify CLR bottlenecks.
Table 17.5: Performance Counters Used to Identify CLR Bottlenecks
Area Counter
Memory Process\Private Bytes
.NET CLR Memory\% Time in GC
.NET CLR Memory\# Bytes in all Heaps
.NET CLR Memory\# Gen 0 Collections
.NET CLR Memory\# Gen 1 Collections
.NET CLR Memory\# Gen 2 Collections
.NET CLR Memory\# of Pinned Objects
.NET CLR Memory\Large Object Heap size
Working Set Process\Working Set
Exceptions .NET CLR Exceptions\# of Exceps Thrown /sec
Contention .NET CLR LocksAndThreads\Contention Rate / sec
.NET CLR LocksAndThreads\Current Queue Length
Threading
.NET CLR LocksAndThreads\# of current physical Threads
Thread\% Processor Time
Thread\Context Switches/sec
Thread\Thread State
Code Access Security .NET CLR Security\Total Runtime Checks
.NET CLR Security\Stack Walk Depth

For more information about how to measure these counters, their thresholds, and their significance, see “ASP.NET” in Chapter 15, "Measuring .NET Application Performance."
Bottlenecks
The following list describes several common bottlenecks that occur in applications written using managed code and explains how you identify them using system counters. For more information about what to measure and how to measure it, see "CLR and Managed Code" in Chapter 15, "Measuring .NET Application Performance."
* Excessive memory consumption: Excessive memory consumption can result from poor managed or unmanaged memory management. To identify this symptom, observe the following performance counters:
* Process\Private Bytes
* .NET CLR Memory\# Bytes in all Heaps
* Process\Working Set
* .NET CLR Memory\Large Object Heap size

An increase in Private Bytes while the # of Bytes in all Heaps counter remains the same indicates unmanaged memory consumption. An increase in both counters indicates managed memory consumption.
* Large working set size. The working set is the set of memory pages currently loaded in RAM. This is measured by Process\Working Set. A high value might indicate that you have loaded a number of assemblies. Unlike other counters, Process\Working Set has no specific threshold value to watch, although a high or fluctuating value can indicate a memory shortage. A high or fluctuating value accompanied by a high rate of page faults clearly indicates that your server does not have enough memory.
* Fragmented large object heap. Objects greater than 83 KB in size are allocated in the large object heap, which is measured by .NET CLR Memory\Large Object Heap size. In many cases, these objects are buffers (large strings, byte arrays, and so on) used for I/O operations (for example, creating a BinaryReader to read an uploaded image). Such large allocations can fragment the large object heap. You should consider recycling those buffers to avoid fragmentation.
* High CPU utilization. High CPU utilization is usually caused by poorly written managed code, such as code that:
* Causes excessive garbage collection. This is measured by % Time in GC.
* Throws a large number of exceptions. This is measured by .NET CLR Exceptions\# of Exceps Thrown /sec.
* Creates a large number of threads. This causes the CPU to spend large amounts of time switching between threads instead of performing real work. This is measured by Thread\Context Switches/sec.

* Thread contention: Thread contention occurs when multiple threads attempt to access a shared resource. To identify this symptom, observe the following performance counters:
.NET CLR LocksAndThreads\Contention Rate / sec
.NET CLR LocksAndThreads\Total # of Contentions

An increase in the contention rate or a significant increase in the total number of contentions is a strong indication that your application is encountering thread contention. To resolve the issue, identify code that accesses shared resources or uses synchronization mechanisms.



Return to HomePage
Microsoft Communities