Troubleshooting Performance Issues in Web Application

There are many options to troubleshoot performance issues in .NET Web Application. We can use ETW, performance logs, IIS logs, application logs, dumps and profiler. Today I am going to show how to use NP .NET Profiler to troubleshoot performance issues. You can download the tool from here

Introduction

.NET CLR runtime provides notification about a variety of events that occur within the .NET application. With the help of these events a .NET Profiler can analyze the performance of .NET application. These events are notified to the profiler via ICorProfilerCallback interface. This interface consist of methods such as FunctionEnter, FunctionLeave, ObjectAllocated, ExceptionThrown,etc. With the help of these events profilers can calculate which functions took long time to execution time, number of exceptions it raised, amount of memory it allocated etc. Click here for more details on profiling API

NP .NET Profiler implements this ICorProfilerCallback profiling interface to profile .NET applications. NP .NET Profiler supports all versions of .NET Runtime on all Windows Operating Systems. It also supports virtual machines.

NP .NET Profiler is designed to assist in troubleshooting performance, memory and first chance exception issues in the following applications:

  • .NET Web Applications
  • WCF Applications
  • .NET Windows Services
  • WPF Applications
  • .NET Console Applications
  • .NET COM Applications
  • Windows Azure Applications
  • Silverlight Applications

 

Advantages of NP .NET Profiler

 

  • XCopy deployable
    • No need to install or reboot the machine
    • No need to recompile the application code
  • On Closing
    • Nothing left running on the machine
  • Very minimum overhead
    • Namespace based filters and time based filters during data collection, this reduces the amount of logs captured
    • Output files are saved in binary format
  • Generates detailed reports
    • Generates callstack for each and every individual instance of a function
    • Collects CPU consumption per individual instance of a function

 

Steps to collect profiler logs

NP .NET Profiler UI is wizard based. Just follow the wizard...

  1. Extract the NP.zip file to c:\temp\np folder
  2. Launch NP .NET Profiler by double clicking on NP.exe
  3. Click on "New Profiler Run" button on the top left
  4. Select "Start a New Project" and click Next button
  5. Select ".NET 4.0 Framework" and ".NET Web Application"
  6. Click Next button
  7. Select AppPool and click Next button
    • Only this selected AppPool will be profiled
    • If the AppPool list is empty, type in the AppPool name
  8. Select "Troubleshoot Performance Issues" and click Next button
  9. Select "Namespace based filter" and click Next button
  10. Select "Ignore System and Microsoft namespaces" and click Next button
  11. Click Next button
  12. Click "Start Profiling" button
  13. When prompted to restart IIS, click yes
  14. Launch the web application and reproduce the performance issues

 

Reviewing profiler logs

.NET Profiler generated huge number of reports. Here are the reports from a sample MVC Web Application. The problem statement for this test application is: one of the request is taking more than 10 seconds to execute.

  1. Once the test is completed, click on the "Stop Profiling" button in the NP.exe
  2. When prompted to restart IIS, click yes
    • This will restart IIS so that AppPool restarts without the profiler options
  3. Click on "Show Reports" button
    • If NP.exe is closed, launch it again and click on "Open Existing output file"
  4. By default, NP .NET Profiler will display the Total Execution Time report as shown : totalexecutionreport
  5. Select "ASP.NET MVC Actions" in the "Advanced Query" combo box and click Refresh button as shown : MVC
  6. “ASP.NET MVC Actions” query shows the list of MVC requests that got executed during the profiler run. The list is sorted by Total Execution Time. mvcresults
  7. Select the top function and click on the "Individual Execution Time" button as shown : menu_individual
  8. This will show individual instances of function. In my test, there are around 16 instances of this function. One of these instances’ execution time is around 10 seconds
  9. To review the callstack, select a instance of the function and click on the "Show Callstack" button as shown : menu_callstack
  10. Expand the tree nodes
  11. Review the "Exclusive Time" column
  12. Notice one of the subfunction takes more time to execute callstack