SharePoint WFE memory allocation on 32-bit Windows Server
How much memory can my SharePoint web front-end (WFE) servers use? It's a common question, and this post is an attempt to answer it for common scenarios. Briefly: 4 GB is the maximum recommended for most scenarios, though you may be able to use more if you're hosting other applications on the same server, including other web applications.
On 32-bit Windows Server 2003 each application pool can only address 2 GB of RAM because that's the limit of user-mode address space in a 32-bit application. You can reduce this effectively to ~1.5 GB after the CLR and core Framework are loaded. Joel recommends configuring 800 Mb per worker process and he has a slew of other great tips for configuring your Application Pools. Note that the /3GB switch is not supported with SharePoint for allocating more memory to the IIS worker process since it leads to memory instability.
If hosting multiple web applications, you can allocate the web applications into multiple application pools, and make use of more than 4 GB RAM. Note that a maximum of 8 application pools is recommended. For example, it's preferable to run Central Administration on a separate server (usually a MOSS Application Server), but you could run it on a WFE in a different application pool and even with its own Application Pool Identity. The same goes for in-house web service applications, though again, to isolate IIS issues caused by SharePoint and your web services it's advisable to always host custom code away from your SharePoint farm. But if you have a good reason to run your code locally (i.e. you need SharePoint interaction and can't get the job done efficiently with SharePoint's web services), it's possible to create your own application pool and host your custom code there. If more than one Application Pool hosts a SharePoint Web Application (i.e a site with SharePoint content, not one of the administrative or WS interfaces) you'll just need to be sure that the Application Pool Identities remain in synch.
If you're only hosting one SharePoint Web Application, there is no benefit to adding memory beyond 4 GB. If that's your scenario it's probably better to move try to move services off that machine so it can at least take full advantage of what it has. Two candidates to move off the WFE (after the obvious APP / SSP services) are the Central Administration application and Query services.
Other ways to mitigate 32-bit memory issues:
- Follow Joel's guidance on configuring Application Pool Settings particularly: recycle application pools daily at an off-peak time, adjust the ceiling to 800 MB per WP, and keep the number of worker processes at one per Application Pool.
- In all custom code, follow Mike's guidance to dispose of all of the disposable objects that you create, and understand where you're creating them inadvertently. If you don't leak memory, you'll have more memory.
- Avoid using standard views of large lists and lists with a lot of metadata. Think in terms of cells being returned, not just list size, and write custom queries or web parts where lists are unavoidably large. See the whitepaper on dealing with large lists for more information.
- Use queries to avoid walking the object model wherever possible. Don't use the memory-hogging "foreach (SPListItem item in mySPList)" when you can use GetItems() or GetItemsInFolder(),
- Web Gardens. Leave worker process at 1 per application pool, or according to TechNet, "Do not use Web gardens." But. If you see frequent out-of-memory issues (e.g. on a 4 GB WFE with
thousands of users), they may be possible to resolve by increasing
worker processes to 2 (aka create a Web Garden) and cap your memory
ceiling to 600 to 800 MB (i.e. divide the available RAM) per process. This can mitigate OOM errors but two things to consider: 1) performance will degrade, and 2) you should also disable page output caching and the BLOB cache since only one process can get a lock to manage either of these at a time, so successful use of the cache now depends on which thread made the call. That said, if memory is a concern you should probably minimize these caches on collaborative sites anyway since they're intended for sites with relatively static content. Heck, this could be a point of its own.
- Disable page output caching and BLOB caching on collaborative sites, these features are best-suited for relatively static WCM sites.
- Migrate to 64-bit Windows Server
64-bit Windows Server doesn't have this 2 GB-per-process limitation (the user-mode address space goes up to 8 terabytes) so memory added beyond 4 GB will always help. Note that 64-bit doesn't remove the performance risks of large lists, which really stem from inefficient default query strategies and the resulting amount of information coming back from SQL Server. Guidance for configuring the Application Pools is similar; recycling daily is still important, but the ceiling can be much higher. Just beware that the higher you let it go, the inevitable and regular garbage collection will simply have that much more to do.
Further reference
Optimizing Office SharePoint Server for WAN environments
JoelO's Recommendations for SharePoint Application Pool Settings
JoelO's Why WSS 3.0 x64 and MOSS 2007 x64... What's the deal?
[Update: Thanks to Todd Klindt for the guidance against mixing web gardens and BLOB caching, and to Nadeem for stopping me from iterating over lists.]