Why SVCHOST Constantly Swaps 16K of Memory Solved!
Revision: 2-18-09

Applies To...
Windows XP Pro SP1, SP2
Windows XP other versions?

If you watch your Windows Task Manager as much as I do, then you may have noticed a svchost.exe process constantly increasing and then decreasing its memory (working set) by 16K (32K in SP2). It's fairly odd for a program that's not in use to be reallocating the same chunk of memory over and over, especially since svchost is a system process. Although this behavior isn't really a problem, it is enough of a curiosity to spark my own investigation.

Continuing to monitor svchost in Task Manager revealed occasional CPU usage and regular disk I/O usage. However, whether or not these factors were related to the process' memory swapping or each other could not be determined as svchost is a host process for a number of system service libraries (DLLs). In some ways, a service constantly making disk I/O hits in the form of writes and other I/O (querying file attributes, enumerating files, etc.) is odder than the constant memory swapping. Services are supposed to have a minimal impact on system resources; writing to disk constantly permanently cuts into the system performance (though it is very minimal).

Sysinternals' Process Explorer picks up where Task Manager leaves off by displaying what must be all the system information that Windows reports. It can thus help with figuring out what service or services are swapping memory, writing to disk, and using the most CPU. In newer versions of Process Explorer, it can show you what services are attached to a host process; however, as suspected, there are too many different services hosted by the process in question to tell anything. But we can look at the properties of the individual threads and hopefully infer which service is the culprit.

Looking at the process' threads shows a number of statistics, such as their starting addresses, CPU usage, and context switches (the number of times they've been swapped off the CPU). Sorting by context switches, it's clear that one thread is using the most CPU with >20 cswitches compared to the <10 that the other threads have. Looking at its calling stack shows mostly typical system calls except for a few in upnp.dll, the library for the Universal Plug and Play service. UPNP is mainly used for interacting with networked devices. In fact, at the bottom of the thread list, a whole slew of upnp.dll threads show up as being created and then almost immediately destroyed. These threads are all starting in a function called CSOAPRequestAsync::ExecuteRequest(). We can guess from the name that it is a C-style function involving the request of a SOAP (a network messaging protocol) file asynchronously, which could mean that the requested data is not immediately returned but will signal when it is. The request of a SOAP file may explain the disk writes, but we'd need more information to be sure.

To find out what file or files are being written, we can again use Process Explorer to show the handles that a process is using. Handles are unique identifiers for a system resource, such as a file or registry key. Looking at the handles for our target svchost process shows another bizarre occurance happening in sync with the UPNP threads and disk writes. Several files are being created in "\WINDOWS\system32\config\systemprofile\Local Settings\Temporary Internet Files\Content.IE5". This monster of a path can actually tell us a few things as well. First, that the files are being created in the internet cache, which for Windows XP is defaultly an Internet Explorer 5.0 cache. Secondly, it's being put in the system profile, which is like the home directory for system processes (i.e. services).

The next step is of course to go to the directory and look at these files, which have an interesting naming convention of "UD" and then a number in brackets. In these various randomly named cache directories were a whole heap of UD[#] files plus other xml files followed by numbers in brackets, with the newest files using the next available number. After opening the UD[#] files and the other XML files present, I finally realized what was going on here. These were the SOAP files that were being requested, which contained statistics for our router that is UPNP-enabled. Since I have SSDP ("Enables discovery of UPnP devices on your home network.") and UPNP services enabled on my system, the router will show up in the Network Connections as an Internet Gateway. Looking at the properties of this connection allows you to select a option called "Show icon in notification area when connected", which I had enabled. Upon disabling this option, the memory swapping, CPU usage, and disk I/O all cease.

From what I've learned, Windows is constantly asking the router for WAN activity just so it can change the icon that is shown in the systray. But since the router isn't a local device, Windows can't expect a timely response, so the UPNP protocol returns the activity of the router whenever it gets around to it in the form of SOAP XML data. In fact, the UD files are probably named such because they are used to determine Upstream and Downstream activity.

Even with the systray activity icon disabled, whenever you open a UPNP device's status dialog, it behaves the same way as when it's polling activity. This is apparently just the way Windows accomplishes UPNP device communication. But if UPNP is writing the device data to disk, then what's reading it? Although explorer.exe (Windows' shell) would be the likely suspect, it shows no handles being opened for the same files that UPNP writes. However, using Process Explorer's feature to find a window's process confirms that explorer is the owner of the status dialog. Sure enough, closing the dialog stops all disk reads associated with explorer.exe. So UPNP writes the XML files, and then the next time the shell polls the connection status, it reads the files (whether they've been updated or not).

As aforementioned, the solution to stopping the memory swapping is just to disable a UPNP device's activity monitor icon in the systray via the option "Show icon in notification area when connected" in the device's properties. For me, this would be preferable given the performance drain (however slight it is) associated with querying the device and writing its results to disk (not to mention the shell's involvement). The benefits the icon provides are nearly useless since I can see the router's activity lights from where I'm sitting. I was mainly using the systray icon to quickly see the router's status dialog, but that can be reasonably easily reached through the Network Connections control panel anyways.

Further investigation revealed that each time the UPNP device is queried, the directories in the internet cache are enumerated to find the number of the last free file to write to. It's not entirely clear why the files from previous Windows sessions are kept around, but they can slow the enumeration after many sessions. As an alternative to disabling the activity monitor icon, the process may be sped up by deleting the contents of the internet cache at startup with a batch file. However, I can't specify whether this actually improves the process' performance.

The only question that hasn't been answered is the one posed by the topic itself: why does svchost constantly swap 16KB of memory? While I'm not entirely sure of this, my best guess is that the creation of the UPNP thread requires some memory to be allocated for the thread's stack each time. Thus, when the thread is created, 16KB of memory are allocated for it; and when it ends, the 16KB are unallocated.