Modern operating systems take a different view of the resources on the system. Regardless of the form factor, it is important for the OS to more effectively manage resource utilization than in the past. Currently, it is far too easy for a single process to consume available resources (memory, CPU, disk I/O) even when this does not improve the overall performance for end-users. The very role of an OS is to balance resources and make sure you can complete all the things that you want to do on your PC. Much of the manual control present in most OS implementations is designed to work around errant software—software that gets in a state where resource consumption is unbounded. Even if the software is not malicious, which is often the case, the ability to build well-behaved software was limited by the complexity of resource allocation APIs. The modern API set in WinRT is designed for programmers to more easily build software that gets the work done while not “taking over” your PC. This is something that makes all PC form factors and all software better.
In this post, group program manager Bill Karagounis on our Fundamentals team details the behind-the-scenes efforts to reclaim memory even when apps are suspended, and how this all happens without developers needing to worry.
Previous blog posts have discussed the Metro style application model using Windows Runtime. An important attribute of this app model is that apps are suspended when they are no longer visible to the user. Suspending Metro style apps in the background is a good thing, as it conserves CPU for other apps and ensures that background apps don’t cause activity that can consume resources, thereby improving the battery life and increasing responsiveness. This is outlined in detail in Sharif Farag and Ben Srour’s blog post, Improving power efficiency for applications
But what about the memory these apps are taking up when suspended? We pointed out earlier that, as a practical matter, the OS will handle this and that your other processes will not feel memory pressure because there are suspended processes. This was an important design consideration. But we know that some of you are still curious how this will all work.
Starting with the Windows 8 Consumer Preview, whenever Windows detects memory pressure on the system, it will repurpose nearly all
the memory that suspended Metro style apps would otherwise hold onto. Windows 8 can reclaim this memory without having to terminate an app.
Memory, responsiveness, and Metro style apps
For any type of app (Metro style or desktop), Windows tries to regulate physical memory allocations on behalf of that app, regardless of the memory requests it has made. Windows has always behaved this way to keep memory available in anticipation of future app memory needs. Windows is careful to only allocate physical memory to an app when the app tries to touch it, even if the app had “allocated” it earlier. Windows will also page out or repurpose parts of memory from an app if the pages of memory haven’t been touched in a long time.
It is important to understand the goal is not to deny memory to a requesting process, but to delay allocating physical memory as long as possible (until the user actually touches the app) because as with many resources, there is a tendency for software to over-budget. The OS is the place where all these requests come together and it has the information to see that meeting all the fully budgeted requests would ultimately starve every process. Not only would work not complete, but the system will essentially lock up. This happens even if the memory is virtual—instead of running out of RAM, your PC would simply swap pages in and out of disk.
The physical memory given to a process at any point in time is referred to as the “working set” of the process. A private
working set represents physical memory that is unique
to a process. Processes also touch other pages of physical memory that are “shared,” which several processes can reference. When you look at the Processes view in Task Manager, the memory for a specific process is actually its current private
working set. NOTE: For simplicity, when I refer to “working set” in this blog, I mean “private working set.”
When the system starts to run low on available memory, the OS will look in all processes for pages of physical memory that it can repurpose to satisfy other needs in the system, even by paging out memory when necessary. For desktop apps, Windows will try to keep the most important (frequently accessed) pages of memory in the app’s working set; this is because desktop apps expect to be able to run code at any time, even when they’re in the background. It’s a fine balance though: if too many pages of memory were to be removed from a desktop app, it could affect the app’s responsiveness due to additional disk I/O (as the app tries to touch memory that has been paged to disk under the covers).
For a deep dive on Windows memory management, see Mark Russinovich’s “Mysteries of Windows Memory Management Revealed” talks: part 1
& part 2
Metro style apps, however, are different from desktop apps, in that they are usually suspended whenever they are no longer in the foreground. When they’re suspended, they aren’t touching ANY of their memory.
To illustrate, I’ve highlighted a few suspended Metro style apps with memory held in their working sets in the screenshot below.
Suspended apps holding on to memory
NOTE: In the Consumer Preview build, the Suspended status does not show
in the Processes view of Task Manager by default; you have to choose to show it
via an option on the View menu.
If there isn’t memory pressure in a system, it’s actually a good thing (most efficient) to just leave memory in the suspended apps’ working sets. But if there is some memory pressure, the fact that these Metro style apps are suspended presents an opportunity to get almost all the memory in these working sets back for other apps, without terminating them.
Reclaiming memory from suspended Metro style apps
In Windows 8 Consumer Preview, we can efficiently write the whole
(private) working set of a suspended Metro style app to disk, in order to gain additional memory when the system detects pressure.
This process is analogous to hibernating a specific app, and then resuming it when the user switches back to the app. We’re taking advantage of the suspend/resume mechanism of Metro style apps to empty or re-populate an app’s working set.
The sequence of events is described below:
- The Process Lifetime Manager (PLM) detects memory pressure in the system and asks the Memory Manager (MM) to empty the working set of a specific process that houses a suspended Metro style app.
- MM moves the pages of memory from the working set of the app to the operating system’s modified page list (which is a list of memory whose contents are to be written out to disk before being reused).
- The working set pages on the modified page list are written out asynchronously, as dictated by the usual MM policies (written out opportunistically in the background, writes triggered when under memory pressure).
- Even after the suspended apps working set is written to disk, the memory pages removed from a process are left intact on the operating system’s standby list. This is a cache of useful pages of memory that can be repurposed for other apps, if necessary. If these pages are immediately needed again by their original process, they are quickly moved back.
If a user switches back to the app while its working set pages are still in physical memory (on the modified page list or the standby list), it’s straightforward: the pages will be added back into the app’s process immediately. If they are no longer available, Windows will read in the app’s working set from disk in an optimized manner.
“Reclaiming memory” in action
To get a feel for how this works, let’s walk through an example with real running code.
The initial state is represented by the screenshot above. I had several Metro style apps running on a PC with 2GB of RAM. The Metro style apps were in the background, and therefore Windows suspended them. I then started opening more apps to drive up memory use on the system and trigger the new functionality.
In the next screenshot, below, you’ll notice that I opened some apps in order to introduce additional memory pressure and induce the behavior described above. As you can see, Windows emptied the working sets of the suspended Metro style apps (highlighted).
Working sets of Metro style apps emptied
Let’s compare the “before” and “after” working sets of the original Metro style apps (some of the “after” stats cannot be seen because Task Manager ran out of room to show all 27 launched apps):
| Metro style app
|| Working set before (MB)
|| Working set after (MB)
| Remote Desktop
| Windows Reader
So in this example, we liberated over 250 MB of physical RAM for other apps to use without shutting down the suspended apps.
Responsiveness when reading the working set back in
A test for this new facility is how responsive a suspended app is after its working set contents are emptied and you decide to switch back to the app.
While I was running this test, I used the “Lyrics” app as my indicator of responsiveness. The Lyrics app can display the lyrics of a song as well as play back a music video. When the Lyrics app goes to the background, it gets suspended, which stops the playback.
After driving memory use to the point where working sets were emptied, I opened additional apps and used the system for a while to ensure that a swap back to the app was going to read the working set from disk. I then triggered the switch back to the Lyrics app (below).
Lyrics app’s working set is repopulated
The key indicator I was looking for was how long it would take from the time I triggered the switch back to the app to the point where I could hear sound again. On a low-end machine, with a high memory load, it’s hard to perceive a difference in responsiveness when switching back to the app whose working set was being read from disk compared to when its working set was still in memory. Your mileage will vary though: the larger the working set, the longer it will take to read-in from disk. We’re also continuing to reduce the amount we have to write to disk for Metro style apps and further optimizing this feature.
This functionality is something that everyone with the Consumer Preview release can try for themselves. Just open up a number of Metro style apps and desktop apps to generate some memory pressure, and then switch back to a suspended Metro style app that has had its working set emptied.
NOTE: Windows will still close Metro style apps if memory gets into the critical range. However, this feature will enable a system to run more applications before getting to that point.
Reading in a working set optimally
To have a responsive experience when you switch back to a suspended app whose working set is on disk, we’ve optimized how we write the working set in the first place, so that reading it in is as efficient as possible.
When we write out the working set of a suspended Metro style app, the working set pages are being written out to disk sequentially. This allows us to read the data back into a process using a small number of large sequential disk reads. The screenshot below is from our Windows Performance Analyzer (WPA) tool that comes as part of the Assessment and Deployment Kit (ADK)
, showing a visual representation of disk reads during this process. I’ve highlighted the working set “read-in” I/O. You can clearly see the sequential stream as we repopulate an app’s working set.
Sequential read I/Os to repopulate an app’s working set (WPA Tool)
Reading back sequential data from almost any storage device is really fast. Most rotational disks can achieve between 50-100MB per second. If a storage device is flash-based (like an SSD), you can get upwards of 200MB per second for these reads.
We expect that many apps will take less than a second of I/O to get the working set of a suspended app back into memory.
By definition, all PCs of all form factors have limited physical memory. The challenges of managing memory do not change when you add more physical memory, so long as you are actually running more programs that request more memory.
Several classes of modern software will continue to evolve to use more and more memory – photo editing of giant RAW images, in-memory databases, very large spreadsheets, and so on. Whether these have WinRT-based implementations or desktop implementations, the OS needs to evolve to manage these ever-increasing memory requests. WinRT is an opportunity for programmers to use an API that allows access to all the memory they need while putting the user first in terms of responsiveness and getting work done. I hope you’ll try this out this feature in Windows 8 Consumer Preview.
-- Bill Karagounis