Wednesday, November 25, 2009

More on Excessive Number of SPRequest Warnings

This is a continuation of a the previous posting and covers what I've figured out since then.

First, I'm increasingly convinced that this warning may be less of an issue than I previously believed. The warning threshold is at 8 open SPRequest objects. Opening the default.aspx page in an un-modified team site page creates 11 such objects, which is enough to trigger the warnings. Since pages are cached, subsequent hits don't make the problem worse. When the thread terminates, it looks like everything gets cleaned up properly. So, there may not be an issue beyond the too-liberal use of SPWeb and SPSite which wastes memory.

Second, contrary to some other blog posts, the issue described in KB932621 (probably) isn't directly addressed in Service Pack 1 or Service Pack 2 and probably isn't needed. See this discussion and this one to retrace my steps. Its probably that this hotfix existed for some period of time. It defintely doesn't exist anymore and I'm not sure there is much reason to ask for it.

Third, this article about best practices includes a couple of very useful registry entries that will help separate real issues from potential issues.

I believe the default warning threshold is much too low and should be raised into the 20-25 range in most real-world SharePoint servers. This can be done by adding this key to the registry:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings

LocalSPRequestWarnCount = desired threshold value (That's a DWORD value)

On development servers, you should think about setting a registry key that tells Sharepoint to log SPRequest objects that are never cleaned up when garbage collection runs The log entries will contain the stack trace where the allocation originally occurred. If you see these, and the stack trace includes your code, run SPDisposeCheck.

Here is the key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\HeapSettings SPRequestStackTrace = 1

Monday, November 23, 2009

Potentially excessive number of SPRequest Objects

I've seen this error message in just about every SharePoint 2007 server I've worked with:

"Potentially excessive number of SPRequest objects (xx) currently unreleased on thread yy..."

I spent the day on this one and have yet to get to the bottom of things.

First of all, I'm not all that sure how much to be worried about this. After all, if everyone else has it, what's the big deal?

The obvious source for this problem is a truely unfortunate detail about how the SharePoint API works. The unfortunate part is that while the SharePoint API has a nice shiney .Net layer on top, its really just a bunch of old COM code underneath (probably written in C++). COM objects are reference counted instead of garbage collected. Their .Net wrappers (SPWeb and SPSite) implement IDisposable, and the programmer has to either wrap them in a using clause or call the Dispose() method. If one of these objects is holding instances of another, it can be kind of messy to figure out who has the cleanup duties.

If you don't clean up, the objects hang around for an indefinite period of time in memory. Every page hit adds to the party until finally, the web server kills the worker process (because its taking all the RAM on your server). This does bad things to server performance.

The first and obvious place to look for problems is in your own code. I spent the day going over all our code because I figured that it had to be something we did. I mean, Microsoft wouldn't ship anything this bad, would they? (Keep reading)

During that process, I found a tool called SPDisposeCheck that seems to help find these problems. Has a couple of bugs, but it helped me find about 20 of these problems in our code.

Unfortunately, the development server was still spitting out tons of these messages and leaking like crazy (more that 20,000 bytes per request).

So, I started stripping all of our code out of the server. By the end of the day, I was all the way down to a bare-bones MOSS with absolutely no custom code. What's left was all Microsoft-written. It still leaks like crazy and still spits out lots of errors on every request.

While I was preparing this blog, I ran across this post:

Posters on this forum talk about KB932621, which has something to do with bugs in the Navigation controls on SharePoint that generate the "excessive" SPRequest objects messages. Strangely, I can't find this KB article on Microsoft support.

The posting is about 2 years old. Is this fixed in SP2? Have to keep digging to find out. I'm wondering if I'm going to have to burn a support ticket?

Or maybe I should do what everyone else does, which is ignore it.

Tuesday, November 17, 2009

Setting Master Page in Site Definition

There's a lot of information about this on the MSDN site and in the general internet.

There are at least 4 ways to attach a master page to a SharePoint site definition:

  • Install the master page as a separate feature, then identify the feature in the site's onet.xml. Here's a how-to.
  • Include the master page with the rest of the site definition files, then identify the master in the onet.xml file. Here's another how-to.
  • Write a feature receiver and use code that sets the master page when the site definition is activated. Here's a CodeProject Link with how-to.
  • Install the master page as a separate feature, then staple the feature to the site definition using a feature stapling feature. A link to feature stapling.
  • Add the master page specification to the site pages (using SharePoint Designer or Visual Studio).

IMPORTANT: Comments added to the second link correct an important flaw in the original post. The URL needs to start with a leading slash! ("/_catalogs/masterpage/custom.master")

The big question on my mind right now is how do you decide when to use these techniques.

As far as I can tell, here are the advantages and disadvantages of these various approaches:

  • If you install the master page as its own feature, you can use it on more than one site definition. If you include the master page with the site definition, the page can only be accessed from that site.
  • If you're more confortable with code than you are with XML, then use a feature receiver.
  • If you want to change the master page for one of the stock SharePoint site definitions (like STS), then feature stapling is your only option.
  • If you can't or don't want to write code, you can use SharePoint Designer.