I'm trying to implement a shared memory block that can grow/shrink.
Such a thing should (i think) be possible using the SEC_RESERVE flag in
CreateFileMapping and then MEM_COMMIT with VirtualAlloc. This works for
making the shared memeory grow dynamically. Shrinking, however, is another
story. I can't seem to make VirtualFree work in this particular case.
Any ideas?
here's a demonstration of the problem:
HANDLE shrdMem;
char *test;
shrdMem = CreateFileMapping( // get shared mem. block
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE|SEC_RESERVE, // read/write access, reserve page (no commit)
0, // max. object size
8192, // buffer max. size
"djkhsjkg"); // name of mapping object
test = (char*)MapViewOfFile( // get pointer to shared mem. block
shrdMem, // handle to shared mem.
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
0);
test=(char
*)VirtualAllocEx(GetCurrentProcess(),test,4097,MEM_COMMIT,PAGE_READWRITE); //
memory is now allocated
test[15]=66; // this assignment works ok
bool x=VirtualFreeEx(GetCurrentProcess(),test,4097,MEM_DECOMMIT); // this
fails
tmp=GetLastError(); // this turns out to be 87 which means "bad parameters"
Hi,
You cannot grow or shrink the memory block retruned by the API
MapViewOfFile(), unless you unmap the view first and then map
a new one starting at the same base address and a new size. Also,
the Win32 does not allow you to change the size of the memory
mapped file once you've created it with CreateFileMapping().
http://msdn2.microsoft.com/en-us/library/ms810613.aspx
Kellie.
I'm not trying to change the size of the memory mapped file (in this case
backed by the system pagefile) or the size of the view mapping. The size of
both can be preset to very large values without affecting the actual memory
consumed (=number of physical pages commited).
The idea was to commit and uncommit physical pages as needed. This would
archieve the net effect of growing and shrinking the actual physical memory
consumed (as opposed to the virtual address space).
Like I said (and also demonstrated below), commiting additional pages works
quite well.
It's the opposite of this (i.e. decommiting) that I'm having problems with.
> The idea was to commit and uncommit physical pages as needed. This would
> archieve the net effect of growing and shrinking the actual physical
> memory
> consumed (as opposed to the virtual address space).
You can free physical pages by MEM_RESET'ting a region of
the mapped view and then calling VirtualUnlock on it (if multiple
processes are mapping the view, it needs to be done in every
process).
MEM_RESET marks pages so that if they are ever removed from
the working set, their contents will be discarded and corresponding
PTEs will be set to demand-zero, so the next time such page is
accessed the memory manager will return a zeroed page.
VirtualUnlock on a non-locked region removes all pages in the
region from the working set. Together with MEM_RESET it should
have the effect you want.
--
This posting is provided "AS IS" with no warranties, and confers no
rights.
Your scheme isnt reducing the physical memory consumed - thats managed by
the working set manager that will page out to the page file as it sees fit.
All you are really doing is lowering your footprint in pagefile.sys - which
could be viewed as a noble goal I guess...
"evilhawk" <evil...@discussions.microsoft.com> wrote in message
news:E501736E-C469-4D97...@microsoft.com...
However, you are technically right and I stand corrected.
However, at first glance, it looks as though it wouldn't be worth
implementing since the procedure you describe needs to be repeated for every
viewing process, implying serious synchronization penalties for something
that is not expected to happen very often (i.e shrinking).
> comitting the memory simply means that the page has storage associated
> with it. It can - and will - still be paged out to disk.
Commiting memory does not actually allocate any storage. Physical pages
are allocated on demand when an application touches each virtual page for
the first time (this is called a "demand-zero fault"). Pages that are
committed
but never accessed do not consume any storage.
> Your scheme isnt reducing the physical memory consumed - thats managed by
> the working set manager that will page out to the page file as it sees
> fit. All you are really doing is lowering your footprint in pagefile.sys -
> which could be viewed as a noble goal I guess...
Decommiting a memory range releases both commit charge (sometimes
also incorrectly called "pagefile usage") and physical memory (if any of
the pages in the range were resident, they will go straight to the free
page list).