Windows Vista Sxs Activation Context Cache

Sxs activation model is built on top of Actication Context. To create an activation context, use the API CreateActCtx.

Activation Context is used very frequently in Windows. For example, a simple operation like start notepad, open the common file dialog, select a file, will call CreateActCtx many times (I measured 18 times in Vista). With the adoption of Sxs model in VC++ libraries, the usage of activation context will certainly be much higher.

However, creating an activation context is a very expensive operation. It has to resolve the full assembly binding closure, which includes probing for policies for all the assemblies, probing for each assembly, and parse each manifest. If you have read the output of sxstrace, you will certainly understand there are a lot work during CreateActCtx.

Fortunately, activation context is fairly static. Given a steady state, it is likely the same input to CreateActCtx will always create an activation context with exactly the same content. This makes it an attractively target for caching.

In Windows Vista, Sxs implements an activation context cache. The article discusses some detail of the Vista activation context cache.

1. What to cache

Only applications from local disk are cached. For applications running off network or CD, the cache has no effect.

2. Location of the cache

From this article (https://blogs.msdn.com/junfeng/archive/2007/06/12/activation-context-creation-flow.aspx) , we understand that the real work of CreateActCtx is done in CSRSS.exe. And this is where the cache is. The main reason is so that the activation context can be shared with multiple processes.

Since each session has a copy of CSRSS.exe, the cache is not shared across use login sessions.

3. Life time of the cache

The cache is only stored in memory. The first time CreateActCtx is called, it adds an entry to the cache. Next time when the same CreateActCtx is called, the result is returned from the cache immediately, saving the expensive probing and xml parsing. The cache is lost when the machine reboots.

4. size of the cache

The cache in Vista RTM has a fixed size, with a Least Recently Used (LRU) replacement algorithm. This may change in the future.

5. Cache Key

The activation context stores the parsed content of all manifests in the full assembly binding closure. Ideally, the cache key should be the path of all the manifests, and their last modified time.

However, if Sxs uses that as the key to the cache, it means Sxs will have to do all the expensive probing, parsing, which makes the cache useless.

To make a compromise, Sxs chooses the path of the entry manifest of CreateActCtx and its last modified time as the key. This means, if one of its dependent assemblies has changed, it is necessary to "touch" (i.e. change the last modified time of) the entry manifest for Sxs to see the change.

Here is an example. You may have a manifest myapp.exe.manifest depending on VC80, and you decides to deploy vc80 privately. So you have a private Microsoft.VC80.CRT.manifest. In Vista, when you change Microsoft.VC80.CRT.manifest, in order for Sxs to see the change in this manifest, you need to change the last modified time of myapp.exe.manifest.

5. WinSxs

If the dependent manifests are part of the application, this update requirement is very reasonable. However, if the assembly you depend on is in the global WinSxs store, you may not get a chance to update your manifest when the assembly in Winsxs changes. 

Thus in Vista, Sxs adds a WinSxs store timestamp. Whenever a publisher policy assembly is installed to Winsxs store, Sxs updates the timestamp. The activation context cache saves the Winsxs store timestamp in the cache when the cache is created. When Sxs processes a CreateActCtx request, it checks to see if the cached Winsxs store timestamp matches the real Winsxs store timestamp. If it does not, Sxs throws out the cache, and re-creates it from scratch.

The reason that the timestamp is updated only when a publisher policy assembly is installed, is because Sxs requires a publisher policy when update an assembly in Winsxs store.

6. Disable the SxS Cache

Remember in the post DotLocal (.local) Dll Redirection, we know that for private testing, we can use registry HKLM\Software\Microsoft\WindowsNT\CurrentVersion\Image File Execution Options!DevOverrideEnable:REG_DWORD to enable DotLocal Dll redirection for applications with SxS manifest. Since disabling the SxS cache should be really for testing only, the same registry key is used to disable the SxS cache.