How to troubleshoot performance issues in SharePoint custom code on your own? Part 1 – High Memory Usage
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 memory usage. Note that performance issues in Microsoft development support are divided into different categories; i.e. a) High memory usage; b) High CPU utilization; c) Slow. One of the main things we will need to distinguish is what type of performance issue we are working on. Obviously, this blog article addresses a high memory usage scenario.
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.
There may be special tools or techniques that a Microsoft support engineer uses that depend on the nature of the issue. It is not the intention of this blog to discuss about those special things, but something that any developers can do. Most of the approaches being discussed here will also being used by Microsoft support engineers as well.
When troubleshooting a high memory usage issue, it is either very simple or very hard. Under a single blog article like this one, I only talk about the simple scenario here. The majority of high memory usage in custom SharePoint code related to the instantiation of the SharePoint class objects (e.g. SPSite & SPWeb) but not disposing them in the code after using them.
The quite popular tool SPDisposeCheck (http://download.microsoft.com/download/B/4/D/B4D279A0-E159-40BF-A5E8-F49ABDBE95C7/SPDisposeCheck.msi) is created to check such objects in the dll. This tool is created by Roger Lamb that the results of the tool reference the sections in his own blog articles where he talks about the scenarios. Here are a couple of his articles that worth to take a look:
Since Mr. Lamb already has some quality articles written, I’m not going to repeat what he has covered but talk about something else.
There are two main causes of high memory usage; i.e. a) memory leak; b) high memory usage by design.
How do we know there is a high memory usage issue on a SharePoint site? What is considered high? Basically, we measure the memory usage of the w3wp.exe worker process that runs the SharePoint site; e.g. a quick look into the Task Manager will give a rough idea. If it is using close to or over 1GB of memory in a 32 bits OS, then it’s consider high. In 64 bits OS, having a w3wp.exe process running with 2GB of memory is quite normal, and even up to 4GB. Note that these are just rough figures for reference only that the real life situation could different in a site by site basis.
Another thing to check is to run a Performance Monitor logging to check the w3wp.exe process’s Private Bytes and Virtual Bytes counters in the Process object for a period of time. If you see a trend that the counters keep rises, then there is likely a memory leak. If you see a trend that the memory rise at the beginning, and then kind of goes flat (at a relatively high memory usage value) eventually, then there is a high memory usage.
Personally, I don’t consider high memory usage necessary a problem unless the server cannot handle such memory usage and causing issues to the site. But it will be good to minimize the usage if possible. The problem that introduces a bigger negative impact is memory leak, which means potentially the process will use up all the memory or until a critical issue occur to the site.
The way to handle both types of memory usage issues is quite the same; i.e. code review (if you’re not going to work with a Microsoft support personnel). For memory leak that specific in SharePoint class objects, we are lucky to have the SPDisposeCheck tool. However, developers can put any type of code that uses any class objects in it. There are other non-SharePoint class objects that also need to dispose. A few popular one I have seen are; e.g. WebResponse (also the Stream object from the WebResponse.GetResponseStream method), web service proxy, DirectorySearcher, IO Stream, etc. The general rule is: Whatever objects you use the “new” keyword to instantiate and that class object does expose a Dispose (or Close) method, dispose it. Sometimes it is not only concern memory usage, but also any resources the specific object going to use (e.g. network connections).
Wait, I didn’t say much here that help but just SPDisposeCheck (that a lot of people know about it already) and code review. For another tool that could help troubleshooting performance issues, a code profiler will be nice, but not everyone has access to one of them. There is one that not very friendly but could somewhat do the job (with certain limitations); i.e. NP .NET Profiler. You can read about it (contains some simple walkthroughs):
Can be downloaded from here:
Note that this blog is not meant to give a training or walkthrough how to use the .NET Profiler. Such information can be found in its own site already. I simply mention it and hope that it does help.
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.