Article ID: 108449 - View products that this article applies to.
This article was previously published under Q108449
This article discusses memory management issues such as working set size, nonpaged pool, and locking pages into physical memory via VirtualLock().
Working SetA process's working set is the set of pages that it has currently in memory. The values for maximum working set and minimum working set are hard-coded in Windows NT and are thus impossible to change. There are three values hard-coded for the maximum working set. The value used for maximum working set depends on whether your machine is considered to be a small, medium, or large machine:
Small machine--less than 16 megabytes (MB)The system tries to keep about 4 MB free to reduce the paging that occurs when loading a new process, allocating memory, and so forth. Any free RAM beyond what the system requires is available for the system to use to increase your working set size if your process is doing a lot of paging.
Medium machine--between 16 MB and 20 MB
Large machine--greater than 20 MB
Process pages that are paged out of your process space are moved into the "standby list," where they remain until sufficient free RAM is available, or until system memory is low and they need to be reused. If these pages are accessed by your process while they are still on the standby list and more RAM has become available, they will be "soft-faulted" back into the working set. This does not require any disk access, so it is very quick. Therefore, even though you have an upper limit to the size of your working set, you can still have quite a few process pages in memory that can be pulled back into your working set very quickly.
To minimize working set requirements and increase performance, use the Working Set Tuner, WST.EXE, to order the functions within your code. One way to help an application receive a larger working set is to use the Network application in the Control Panel to set the server configuration to "Maximize Throughput for Network Applications."
Nonpaged PoolSystem memory is divided into paged pool and nonpaged pool. Paged pool can be paged to disk, whereas nonpaged pool is never paged to disk. In Windows NT 3.1, the default amount of nonpaged pool also depends on whether your machine is considered small, medium, or large. In other words, you will have X amount of nonpaged pool on a 16 MB machine, Y amount of nonpaged pool on a 20 MB machine, and Z amount of nonpaged pool on a machine with more than 20 MB (the exact values for X, Y, and Z were not made public).
Important system data is stored in nonpaged pool. For example, each Windows NT object created requires a block of nonpaged pool. In fact, it is the availability of nonpaged pool that determines how many processes, threads, and other such objects can be created. The error that you will receive if you have too many object handles open is:
Many 3.1 applications ran into this error because of the limited amount of nonpaged pool. This limit were addressed in Windows NT 3.5. We found that:
In Windows NT 3.1, every time an object was shared, quota was charged for each shared instance. For example, if you opened a file inheritable and then spawn a process and have it inherit your handle table, the quota charged for the file object was double. Each handle pointing to an object cost quota. Most applications experienced this problem. Under Windows NT 3.5, quota is only charged once per object rather than once per handle.
Windows NT 3.1 had a fixed quota for paged and nonpaged pool. This was determined by the system's memory size, or could be controlled by the registry. The limits were artificial. This was due to the poor design of quotas with respect to sharing. It was also affected by some objects lying about their actual resource usage. In any case, Windows NT 3.5 has revised this scheme.
The Windows NT 3.1 "Resource Kit, Volume I" documents that it is possible to change the amount of nonpaged pool by modifying the following registry entry:
WARNING: This modification can cause the system to crash, and therefore Microsoft does not recommend that this registry entry be changed.
HKEY_LOCAL_MACHINE\SYSTEM\ CurrentControlSet\ Control\ Session Manager\ Memory Management\ NonPagedPoolSize
Quotas can still be controlled in Windows NT 3.5 using these Windows NT 3.1 registry values. However, this technique is now almost never needed. The new quota mechanism dynamically raises and lowers your quota limits as you bump into the limits. Before raising a limit, it coordinates this with the memory manager to make sure you can safely have your limit raised without using up all of the systems resources.
VirtualLock()To lock a particular page into memory so that it cannot be swapped out to disk, use VirtualLock(). The documentation for VirtualLock() states the following:
Locking pages into memory may degrade the performance of the system by reducing the available RAM and forcing the system to swap out other critical pages to the paging file. There is a limit on the number of pages that can be locked: 30 pages. The limit is intentionally small to avoid severe performance degradation.There is no way to raise this limit in Windows NT 3.1--it is fixed at 30 pages (the size of your working set). The reason that you see a severe performance degradation when an application locks these pages is that Windows NT must reload all locked pages whenever there is a context switch to this application. Windows NT was designed to minimize page swapping, so it is often best to let the system handle swapping itself, unless you are writing a device driver that needs immediate access to memory.
Windows NT 3.5 allows processes to increase their working set size by using SetProcessWorkingSetSize(). This API is also useful to trim your minimum working set size if you want to run many processes at once, because each process has the default minimum working set size reserved, no matter how small the process actually is. The limit of 30 pages does not apply to VirtualLock() when using SetProcessWorkingSetSize().
Article ID: 108449 - Last Review: November 21, 2006 - Revision: 3.2