Inside SQL Server 2000's Memory Management Facilities
Ken Henderson
In this column,we'll explore the internals of SQL Server memory management from
a developer's perspective.That is,we'll discuss the way the server manages memory in
terms of the APIs and operating system facilities it makes use of and how they work.
Exploring a product in this fashion helps us get inside the heads of the developers who
built it and helps us understand how they intended it to be used. Understanding how a
product works internally and its intended use is key to mastering it.
We'll begin our investigation by first covering some basic Windows memory
management fundamentals. Like all 32-bit Windows applications, SQL Server makes
use of Windows memory management facilities to allocate, free, and generally
manage memory resources. It calls Win32 memory management API functions to
interact with the memory resources provided by the operating system in the same way
that any Windows application does.
Because nearly all memory allocations within SQL Server make use of virtual
memory (rather than heaps), most allocation code eventually resolves to a call to the
Win32 VirtualAlloc or VirtualFree API function. The server calls VirtualAlloc to
reserve and commit virtual memory and VirtualFree to free virtual memory.
Virtual Memory vs. Physical Memory:
On the x86 family of processors, Windows provides all processes a 4GB virtual
memory sandbox in which to play. By "virtual," I mean that the memory isn't memory
in the traditional sense. It is merely a range of addresses with no physical storage
implicitly associated with it. As a process makes memory allocations, these addresses
are used and physical storage is associated with them. However, this physical storage
is not necessarily (and not usually) physical memory. It is usually disk drive space.
Specifically, it is space in the system paging file(s). This 4GB address space is divided
into two partitions: the user mode partition and the kernel mode partition. By default,
each of these is sized at 2GB, though you can change this through BOOT.INI switches
on the Windows NT® family of the operating system (OS). (Windows NT, Windows
2000, Windows XP, and Windows Server™ 2003 are members of the Windows NT
family; Windows 9x and Windows ME are not.)
Memory Regions:
SQL Server organizes the memory it allocates into two distinct regions: the BPool
(buffer pool) and MemToLeave (memory to leave) regions. If you make use of AWE
memory, there's actually a third region: the physical memory above 3GB made
available by the Windows AWE support.
The BPool is the preeminent region of the three. It is the primary allocation pool
in SQL Server, serves primarily as a data and index page cache, and is also used for
memory allocations less than 8KB. MemToLeave consists of the virtual memory
space within the user mode address space that is not used by the BPool. The AWE
memory above 3GB functions as an extension of the BPool and provides additional
space for caching data and index pages.
So, once SQL Server has started, the BPool has been reserved, but not committed,
and the MemToLeave region is essentially free space within the virtual memory
address space of the process. As I said earlier, reserved space is just address space—it
does not have physical storage behind it until it is committed. Over time, the amount
of memory committed to the BPool will increase until it reaches the upper limit
computed when the server was originally started.
Monitoring SQL Server Virtual Memory Use
You can track the computed maximum size of the BPool via the SQL Server:Buffer
Manager\Target Pages Perfmon counter. Because most of SQL Server's virtual
memory usage comes from the BPool, these two counters will, generally speaking,
increase or level off in tandem (keep in mind that, when AWE support has been
enabled, the Private Bytes counter won't reflect the entirety of SQL Server's memory
use). If the Total Pages counter levels off but the Private Bytes counter continues to
climb, this usually indicates continued allocations from the MemToLeave region.
Allocations:
A memory consumer within the server initiates a memory allocation by first creating a
memory object to manage the request. When the object allocates the request, it calls
on the appropriate memory manager within the server to fulfill the request from either
the BPool or the MemToLeave region. For requests of less than 8KB, the request is
usually filled using memory from the BPool. For requests of 8KB or more of
contiguous space, the request is usually filled using memory from the MemToLeave
region. However, xprocs are a special exception. When an xproc calls the Open Data
Services srv_alloc API function, it is treated just like any other consumer within the
server. Generally speaking, srv_alloc requests for less than 8KB of memory are
allocated from the BPool. Larger allocations come from the MemToLeave space.
The Memory Manager:
As the server runs, the memory manager checks to make sure that a given amount
of physical memory remains available on the server so that Windows and other
applications on the server continue to run smoothly.
There is a separate free list for each CPU on the system. When a free page is
needed to satisfy an allocation request, the free list associated with the current CPU
requesting the allocation is checked first, followed by the lists for the other CPUs on
the system. This is done to improve scalability by making better use of the local cache
for each processor on a multiprocessor system. You can monitor a specific BPool
partition via the SQL Server:Buffer Partition Perfmon object. You can monitor the
free list for all partitions via the SQL Server:Buffer Manager\Free Pages Perfmon
counter.
So, throughout
the time that it runs, SQL Server's memory manager process
monitors the memory status of the system to be sure that a reasonable amount of free
physical memory remains available to the rest of the system and that a healthy number
of free pages remains available for use by new memory allocation requests. The
BPool begins by acquiring and locking physical memory on the machine. The amount
of memory it locks varies based on whether maximum server memory has been set. If
it has, the BPool attempts to lock the amount specified by maximum server memory.
If it has not, the BPool locks all of the physical memory on the machine except for
approximately 128MB, which it leaves available for other processes. The BPool then
uses the physical memory above 3GB (the AWE memory) as a kind of paging file for
data and index pages. It maps physical pages from this region into the virtual memory
address space as necessary so they can be referenced via 32-bit pointers.