I’ve just uploaded a new open-source project called “Non-Paged CLR Host” to CodePlex, in collaboration with Alon Fliess. This project features a custom CLR host that can be used for executing any existing .NET application with little or no modification. This custom CLR host ensures that all memory given out to the CLR is locked into physical memory if possible, thus eliminating paging completely.
This can provide two important and distinct advantages to server and client applications alike:
- Applications will benefit from no paging during normal operation. Even if other applications are actively allocating memory, allocations performed under the non-paged CLR host will be locked into physical memory.
- No paging will occur when the application is idle, providing a great benefit to low-latency processes such as GUI applications (even if the user has fallen asleep in front of the monitor). The normal working set management scheme employed by Windows will not affect processes running under the non-paged CLR host.
The non-paged CLR host is available in x86 (32-bit) and x64 (64-bit) builds. You can compile your own flavor for Windows 2000 and above on any supported processor. Please note that this is a preliminary version that has not been extensively tested, so we strongly recommend that you use it in a controlled environment for testing purposes only.
Using the non-paged CLR host is extremely simple. The current host consists of a console application that executes an assembly passed to it via the command line. The only constraint imposed on the code to be executed is that it must reside in a static method which returns an int and accepts a string as a parameter (note: not string), such as the following method:
#pragma warning disable 0028
public static int Main(string str)
#pragma warning restore 0028
(Warning CS0028 indicates that you have a Main method with a mismatched signature.) Assuming that this method is placed in a class called Program that resides in an assembly called TestHost.dll, the following command line can be used to execute it:
AweClrHost_Win32_Release.exe TestHost.dll Program Main
You can also pass the parameter to the Main method on the same command line. It defaults to the minimum working set size reservation that the host has been able to reserve for the process (as a string).
From an implementation perspective, the non-paged CLR host uses the SetProcessWorkingSetSize, SetProcessWorkingSetSizeEx (on Windows Server 2003 and above) and VirtualLock APIs to ensure that memory allocated by it is locked into physical memory. Note that using the above APIs does not guarantee with absolute certainty that no paging will occur; instead, it minimizes the odds of it occurring to very exceptional scenarios. (And from a practical perspective, they are really unlikely.) In some load tests I conducted, even when the system as a whole was hogged by lack of physical memory, no page faults were observed in the process using the non-paged CLR host. In future posts, we will (hopefully) delve into the implementation highlights of a custom CLR host and some of the surprises that lurk along the way.
Wrapping this up, Alon and I will be very glad to hear about your experiences with this preliminary release. There are many interesting scenarios that can benefit from using the non-paging CLR host, and we would appreciate any such scenarios you might have encountered or any other kind of feedback. You can contact me through the blog, as usual. Alon can be contacted through his blog as well.