Understanding IIS 7.5 Worker Process Metrics: Virtual Bytes vs. Private Bytes vs. Task Manager Memory Reporting


4 views

When monitoring IIS worker processes, you'll encounter three different memory measurements that often cause confusion:

IIS Manager shows:
Private Bytes (KB): 106,435.00
Virtual Bytes (KB): 748,788.00

Task Manager shows:
Memory (Private Working Set): 69,276K

Virtual Bytes represents the total amount of virtual address space the process has allocated. This includes:

  • Committed memory (in physical RAM or page file)
  • Reserved memory (address space reserved but not yet used)
  • Shared DLLs and memory-mapped files

Private Bytes specifically tracks memory allocated privately by the process that cannot be shared with other processes.

Task Manager's "Memory (Private Working Set)" shows only the portion of private bytes currently in physical RAM. The discrepancy occurs because:

Private Bytes (IIS) = 106,435 KB 
   → Includes both RAM and paged-out memory
Task Manager = 69,276 KB 
   → Only shows RAM-resident portion

Here's how to check these values programmatically using PowerShell:

# Get memory stats for all w3wp processes
Get-Process w3wp | Select-Object ProcessName, 
    @{Name="PrivateBytes(MB)";Expression={$_.PrivateMemorySize64/1MB}},
    @{Name="VirtualBytes(MB)";Expression={$_.VirtualMemorySize64/1MB}},
    @{Name="WorkingSet(MB)";Expression={$_.WorkingSet64/1MB}}

High virtual bytes might indicate:

  • Memory fragmentation (common in long-running processes)
  • Excessive DLL loading
  • Memory leaks in unmanaged code

For ASP.NET applications, consider adding this to Global.asax to track allocations:

protected void Application_EndRequest(object sender, EventArgs e)
{
    Debug.WriteLine($"Virtual: {Process.GetCurrentProcess().VirtualMemorySize64/1024}kb");
    Debug.WriteLine($"Private: {Process.GetCurrentProcess().PrivateMemorySize64/1024}kb");
}

For production monitoring, use these performance counters:

Process(w3wp)\Virtual Bytes
Process(w3wp)\Private Bytes
Process(w3wp)\Working Set
.NET CLR Memory#Bytes in all Heaps

When monitoring IIS worker processes, you'll encounter three key memory metrics that often cause confusion:

Private Bytes (KB) 106,435.00
Virtual Bytes (KB) 748,788.00
Task Manager Memory: 69,276K

Virtual Bytes represents the total address space a process has allocated, including:

  • Committed memory (in physical RAM or page file)
  • Reserved memory (address space reserved but not yet used)
  • Shared memory regions

Private Bytes specifically tracks memory exclusively allocated to the process (non-shared), which includes:

  • Heap allocations
  • Private data segments
  • Memory-mapped files with private copies

Task Manager typically displays the Working Set - the subset of virtual bytes currently in physical RAM. The 69,276K value you see represents:

Working Set = Private Working Set + Shared Working Set

Here's how you might monitor these values programmatically:

using System.Diagnostics;

public class IISMemoryMonitor
{
    public static void LogMemoryStats(int processId)
    {
        Process proc = Process.GetProcessById(processId);
        
        Console.WriteLine($"Private Bytes: {proc.PrivateMemorySize64 / 1024} KB");
        Console.WriteLine($"Virtual Bytes: {proc.VirtualMemorySize64 / 1024} KB");
        Console.WriteLine($"Working Set: {proc.WorkingSet64 / 1024} KB");
        
        PerformanceCounter privateBytesCounter = new PerformanceCounter(
            "Process", "Private Bytes", proc.ProcessName);
        Console.WriteLine($"Perf Counter Private Bytes: {privateBytesCounter.NextValue() / 1024} KB");
    }
}

When Virtual Bytes is significantly higher than Private Bytes:

  • Check for memory fragmentation in your application
  • Review large memory-mapped files usage
  • Investigate native DLLs that might reserve address space

For deeper analysis, use these tools:

  1. VMMap from SysInternals
  2. DebugDiag for memory dumps
  3. Windows Performance Recorder for memory patterns