How to troubleshoot performance issues in SharePoint custom code on your own? Part 2 – High CPU Utilization

This post is a contribution from Paul Chan, an engineer with the SharePoint Developer Support team

One of the popular performance issues I have seen when working on customer’s issues is high CPU utilization (aka 100% CPU, or high CPU).

NOTE: If you feel needed or press on time, feel free to contact Microsoft and create a support case to work with us, instead of dragging the resolution of the issue for too long until the last minute.

When troubleshooting a high CPU issue on your own (i.e. not working with a Microsoft support engineer), it could be very complicated. Most of the time there isn’t much can be done but code review.

The first thing to confirm is which process is running on high CPU. This can be verified by simply looking into the Task Manager of the server. If it is a custom code on SharePoint server, the w3wp.exe process is what we’re looking into.

From my experience, there is about 40% of the time a high CPU issue actually caused by high memory usage. What could happen is the memory usage is too high that it triggers .NET garbage collection (GC) more often than it should have. Since GC is an expensive operation, the CPU will go high whenever GC is occurring. In such situation, resolving the high memory issue will lower down the CPU usage. Check the memory usage of the w3wp.exe process will give you an idea if it’s running on high memory or not (or take a look to the article “How to troubleshoot performance issues in SharePoint custom code on your own? Part 1 – High Memory Usage”).

What if the memory usage appears normal? Then we move on to code review. What to focus is any type of loop, foreach, while, etc. and any repeated operations. It is usually not a single call of API will lead to 100% CPU, but a lot of API calls that being executed repeatedly.

Another way “try” to find out where in the custom code that leads to 100% CPU is to logging. Simply add some logging/reporting code (e.g. write to a text file, SharePoint list, etc.) in the code from the beginning to the point that you suspect where the issue could be. When the log shows that an expected entry (and further) is missing, then it means the issue occurs after the last recorded entry and before the missing entry, because the code being executed before the logging is too busy that it doesn’t get the chance to execute the logging piece until after a long time. This could help narrow down the focus in the code.

There seems no clear way to identify a line of code that uses large amount of CPU power. What exactly need is the information about the CPU usage of a thread in the process. Since w3wp.exe process is going to run multiple threads, getting the CPU % from the w3wp.exe process cannot identify which thread is using high CPU. Even if we can tell which thread is using high CPU (e.g. from Performance Monitor’s Thread object, % User Time counter), we still need to tell what kind of code a specific thread is executing. Is this impossible? No, but it is a bit tricky try to get such information in a practical world. The type and amount of information to describe the process will not fit in this little blog article however.

NOTE: For any performance issues that you don’t feel comfortable to handle, please feel free to create a support case and work with Microsoft support.