Optimizing w3wp.exe Memory Usage in Small Business Server 2011: IIS Application Pool Tuning Strategies


2 views

Small Business Server 2011's default configuration creates a perfect storm for memory consumption with its 7 sites and 20 ASP.NET application pools. The w3wp.exe processes, especially for WSUS, can balloon up to 800MB each, collectively consuming over 4GB of RAM. While manual recycling provides temporary relief, it's not a sustainable solution for production environments.

The common argument that "memory will be freed when needed" doesn't hold water in SBS environments for two critical reasons:

  • File server performance suffers when memory isn't truly available for filesystem caching
  • Actual memory release during shortages is minimal (often <100MB), leading to excessive swapping

Here are specific IIS configuration adjustments to implement:

// Set memory-based recycling (add to applicationHost.config)
<applicationPools>
    <add name="WSUSPool">
        <recycling logEventOnRecycle="Memory">
            <privateMemory limit="300000" /> // 300MB limit
        </recycling>
        <processModel idleTimeout="20" /> // Minutes before shutdown
    </add>
</applicationPools>

For pools serving rarely-used applications (like Remote Web Workplace), consider:

// PowerShell script to monitor and recycle excessive consumers
Get-ChildItem IIS:\AppPools | Where-Object {
    (Get-Process -Id $_.WorkerProcesses.ProcessId).WorkingSet -gt 500MB
} | ForEach-Object {
    Write-Host "Recycling $($_.Name)"
    $_.Recycle()
}

To prioritize cache memory, add this registry tweak:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]
"LargeSystemCache"=dword:00000001
"SystemPages"=dword:00000000

Implement performance counter logging to track improvements:

logman create counter IISMemoryLog -o "C:\PerfLogs\IISMemory.blg" -c \
"\Process(w3wp*)\Working Set" "\Memory\Cache Bytes" \
"\Web Service(_Total)\Current Connections" -f bincirc -v mmddhhmm -si 00:15

In Small Business Server 2011 environments, we often observe 7-20 ASP.NET application pools (for SharePoint, Exchange, WSUS, etc.) collectively consuming over 4GB RAM. The WSUS pool alone can reach 800MB working set. While conventional wisdom suggests Windows memory management will handle this automatically, the reality for multi-role SBS servers differs significantly:

// Sample PowerShell to check current memory usage
Get-Process w3wp | Sort-Object -Property WS -Descending | 
    Select-Object Id, ProcessName, WS, @{Name="WS(MB)";Expression={[math]::round($_.WS/1MB,2)}}

The core issue stems from three fundamental mismatches:

  • File server performance heavily depends on available memory for cache
  • IIS application pools maintain aggressive memory retention
  • Memory pressure triggers paging rather than substantial w3wp memory release

Instead of blanket recycling, implement targeted solutions:

# Application Pool Memory Limitation (appcmd)
%windir%\system32\inetsrv\appcmd set apppool /apppool.name:WSUSPool /recycling.periodicRestart.privateMemory:500000

For WSUS specifically, add this web.config modification:

<configuration>
  <system.web>
    <httpRuntime maxRequestLength="4096" 
               enable="true" 
               requestLengthDiskThreshold="256"
               executionTimeout="3600"
               shutdownTimeout="90"
               delayNotificationTimeout="5"
               waitChangeNotification="0"
               maxWaitChangeNotification="0"
               enableKernelOutputCache="true"/>
  </system.web>
</configuration>

Create a PowerShell script that monitors and recycles based on actual usage:

$MaxMemoryMB = 400
$AppPoolName = "WSUSPool"

$process = Get-Process w3wp | Where-Object {$_.ProcessName -eq "w3wp" -and $_.Modules.ModuleName -like "*$AppPoolName*"}
if ($process.WorkingSet64 / 1MB -gt $MaxMemoryMB) {
    Import-Module WebAdministration
    Restart-WebAppPool -Name $AppPoolName
    Write-EventLog -LogName Application -Source "WSUS Memory Monitor" -EntryType Information -EventId 1001 -Message "Recycled $AppPoolName for exceeding $MaxMemoryMB MB threshold"
}

For SBS servers handling file services, prioritize kernel memory:

# Set IIS to favor kernel caching (requires registry edit)
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\InetInfo\Parameters" -Name "DisableMemoryCache" -Value 0
Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Services\InetInfo\Parameters" -Name "MaxCachedFileSize" -Value 65536

Implement performance counters to track effectiveness:

# Create custom data collector set
logman create counter IIS_Memory_Tracking -o "C:\PerfLogs\IIS_Memory.blg" -c "\Process(w3wp*)\Working Set" "\Memory\Available MBytes" "\Web Service Cache\File Cache Hits %" -f bin -v mmddhhmm -si 00:01:00