Holy cow, I wrote a book!
If you try to run the
sample program demonstrating how to create a file mapping using
you'll probably run into the error
(Not all privileges or groups referenced
are assigned to the caller)
when calling AdjustTokenPrivileges.
What is going on?
The AdjustTokenPrivileges enables privileges that you
already have (but which are masked).
Sort of like how a super hero can't use super powers
while disguised as a normal mild-mannered citizen.
In order to enable the
you must already have it.
But where do you get it?
You do this by using the
group policy editor.
list of privileges
says that the SeLockMemoryPrivilege
corresponds to "Lock pages in memory".
Why does allocating very large pages require permission to lock
pages in memory?
Because very large pages are not pageable.
This is not an inherent limitation of large pages;
the processor is happy to page them in or out,
but you have to do it all or nothing.
you don't want a single page-out or page-in operation
or 16MB of disk I/O;
that's a thousand times more I/O than your average paging operation.
And in practice, the programs which use these large pages
are "You paid $40,000 for a monster server whose sole purpose is
running my one application and nothing else" type applications,
like SQL Server.
Those applications don't want this memory to be pageable anyway,
so adding code to allow them to be pageable
is not only a bunch of work,
but it's a bunch of work to add something nobody who uses the feature
What's more, allocating very large pages can be time-consuming.
All the physical pages which are involved in a very large page must
be contiguous (and must be aligned on a large page boundary).
Prior to Windows XP, allocating a very large page can take
15 seconds or more if your physical memory is fragmented.
(And even machines with as much as 2GB of memory will probably have
highly fragmented physical memory once they're running for a little
allocating the physical pages for a very large page is performed
by the kernel function which allocates physically contiguous memory,
which is something device drivers need to do quite often for
I/O transfer buffers.
Some drivers behave "highly unfavorably" if their request for
contiguous memory fails, so the operating system tries very
hard to scrounge up the memory, even if it means shuffling
megabytes of memory around and performing a lot of disk I/O
to get it.
(It's essentially performing a time-critical defragmentation.)
If you followed the discussion so far,
you'll see another reason why large pages aren't paged out:
When they need to be paged back in,
the system may not be able to find
a suitable chunk of contiguous physical memory!
In Windows Vista,
the memory manager folks recognized that these long delays
made very large pages less attractive for applications,
so they changed the behavior so requests for very large pages
from applications went through the "easy parts" of looking
for contiguous physical memory, but gave up before the
memory manager went into desperation mode,
preferring instead just to fail.
(In Windows Vista SP1,
this part of the memory manager was rewritten so
the really expensive stuff is never needed at all.)
Note that the MEM_LARGE_PAGES
flag triggers an exception
to the general principle that MEM_RESERVE only reserves
MEM_COMMIT makes the memory manager guarantee that
physical pages will be there when you need them,
and that the physical pages aren't actually allocated until you
access the memory.
Since very large pages have special physical memory requirements,
the physical allocation is done up front so that the memory manager
knows that when it comes time to produce the memory on demand,
it can actually do so.