So far I touched on
subjects that have been widely discussed in the industry. Today I would
like to talk about a subject that you would hardly find information
about: memory pressure.. On a surface the subject appears simple but in reality this is not the case.
There are two types of
memory pressure a process can be exposed to external and internal. To
maximize its performance and reliability a process might want to react
to both of them. External memory pressure might cause a process and
whole system go into paging . Internal memory pressure might cause OOM
conditions and eventual process's crash.
External memory
pressure is controlled by Windows, operating system. There are two types
of external memory pressure such as physical dynamic memory pressure
and physical “static” memory pressure. The latter type happens when a
system runs out of page file. This type of memory pressure might drive
the whole system into OOM condition. You might have seen those pop ups
in the right corner indicating that system runs low on virtual memory.
In order to detect this type of pressure one needs to monitor the size
of page file. Usually applications don’t do it.
The external dynamic
memory pressure rises when Windows runs low on free RAM and about to
start trimming existing working sets on the box, i.e paging. A process
can monitor this type of pressure by leveraging memory resource notification API described here http://msdn.microsoft.com/library/default.asp?url=/library/en-us/memory/base/querymemoryresourcenotification.asp. An
application can have dedicated thread that listens on memory resource
notifications. Keep in mind that these notificaitons are global, i.e.
they are shared by all processes. There are two types of memory resource
notifications that a thread can wait on: memory high and memory low.
Before Windows starts paging it will turn on low memory resource
notificaion. Applications’ threads that waiting on such notification
will be waken up and given opportunity to shrink process’s memory usage
before OS comes into the picture. This is very useful for highend
services that have better idea than the operating system about their
memory usage and what needs to be shrunk. Once memory goes back to
normal Windows unsets the low memory resource notification. As you might
expect, when Windows thinks there is a plenty of memory on the box, it
turns on memory high resource notification. If both of the
memory resource notifications are not set it means that system is in
stable state and processes shouldn’t either grow or shrink.
There
are two types of internal memory pressure such as physical memory
pressure and Virtual Address Space, VAS, pressure. Depending on its
memory manager there are several ways for a process to get into physical
internal memory pressure. For example external pressure might cause a
process to shrink. This might trigger process’s releasing memory which
in its turn will trigger internal memory pressure. The other possibility
to get into this type of pressure is if an administrator sets memory
limits for a process. Once max is reached process will get into internal
memory pressure. Usually application recovers from this type of
pressure by shrinking internal caches and pools back to its memory
manger. In cases when there is no external memory pressure there is no
reason to free this memory back to operating system.
VAS
pressure is the most difficult one to detect and react to. VAS pressure
could happen due to two reasons. The first reason is VAS fragmentation.
It happens when a process might
have plenty of VAS regions but there is no a VAS region of a given size
available. Currently there is no easy way to detect largest free VAS
region. One could try to allocate a VAS region of given size to identify
VAS pressure state. Be careful though, periodic attempt to allocate a
VAS region of large sizes, say 4MB, might cause VAS fragmentation. This
will happen if some component in the process keeps on allocating and
caching VAS regions of smaller sizes, for example threads. The second
reason for VAS pressure is the whole VAS could be consumed. In this case
any VAS allocation fails. High-end servers have to be able to deal with
VAS pressure especially on 32 bit platforms. Not recovering from VAS
pressure might cause first process's slowing down and then terminating.
When an application detects VAS pressure it could react to it the same
way as to internal physical pressure by shrinking caches and pools. In
addition a process might decide to shrink thread pools, remove shared
memory regions, unload dlls and etc…
To
correctly handle all types of memory pressure you will need to build
special infrastructure. As it turns out this type of infrastructure is
not simple. Just consider different states your process can be in at the
same time. For example Windows might indicate that there is plenty of
external RAM, enabling your process can grow, but at the same time your
process can hit internal physical or VAS pressure.
There are several implementation caveats that you need be aware of when implementing such infrastructure. If
your process slow enough to react to external pressure Windows will
page your process out. Then it will turn off low memory resource. Once
it seesm that there is plenty of memory it will turn on high memory
resource. In this case you might see that high is on and start
allocating more memory even though your process is paged out. This might
cause your process to page against itself. It seems that when deciding
to grow you need to take your working set into account, please remember
neither AWE pages nor large pages are part of working set so you have to
be really careful. The other caveat is when running low on paging file,
Windows won’t turn on low memory resource even though it is about to
return OOM for next memory requests. In addition keep in mind that your
well behaved application can be affected by a bad one that doesn’t care
about memory state on the box at all.
Understanding
memory pressure should really help you when we will be discussing SQL
Server memory manger. Moreover having this knowledge should help you to
administrate SQL Server and other applications sharing a box