Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New Windows 8.1 APIs for virtual memory management: `DiscardVirtualMemory()` vs `VirtualAlloc()` and `MEM_RESET` and `MEM_RESET_UNDO`

Windows 8.1/Server 2012RC2 just introduced new APIs for virtual memory management: OfferVirtualMemory(), ReclaimVirtualMemory(), DiscardVirtualMemory(), which their usage is pretty straightforward, just by looking at their names.

The thing I can't get is how these APIs work against VirtualAlloc() plus the flags MEM_RESET and MEM_RESET_UNDO, and what are the subtle differences.

For the OfferVirtualMemory(), MSDN says that is very similar to VirtualAlloc()+MEM_RESET, except that it removes pages from the working set, and restrict further accesses to the pages.

So, basically it restricts accesses to the pages, and if I want to access those pages again I must call ReclaimVirtualMemory(). That's fine, but shouldn't MEM_RESET also remove pages from the working set? Shouldn't MEM_RESET act as the POSIX MADV_DONTNEED flag of madvise(2) which basically removes pages from the process' pages tables, and if I access those pages again in the future, the access will generate a soft-fault, and those pages will be reallocated again, initialized to zero.

If this is true, of course, pages are removed from the working set of the process, because they basically get deallocated, even if the process keeps the virtual addresses allocated, and see them "committed".

Now, let's see DiscardVirtualMemory(): here MSDN says nothing about MEM_RESET flag, but if I read the description of this API, it seems really the same thing as VirtualAlloc()+MEM_RESET.

So, does anyone know if there are some differences between those APIs, and what are the proper use cases of those subtle differences? If they introduced a comopletely new API like DiscardVirtualMemory(), there should be some difference with the old method.

If I want to port an application from POSIX which uses madvise(2) with MADV_DONTNEED and MADV_WILLNEED, what is the best way to mimic this POSIX behavior? Until now, I used VirtualAlloc()+MEM_RESET for MADV_DONTNEED and VirtualAlloc()+MEM_RESET_UNDO for MADV_WILLNEED. Is that ok, or I can do better with those new APIs?

like image 421
Marco Pagliaricci Avatar asked Oct 19 '22 04:10

Marco Pagliaricci


1 Answers

DiscardVirtualMemory on MSDN

When the region of memory is again accessed by the application, the backing RAM is restored, and the contents of the memory is undefined.

If I read between the lines, that says,

  • some of what was there might still be there when you access it
  • it is allowed to give you garbage initialized pages when those pages commit
  • if the machine was actually constrained for memory, some pages will probably be zero initialized sometimes

This is not what would happen if you reset the virtual address range using the older API. In that case, there is a guarantee to provide zero initialized pages when you access those pages later.

This enables the possibility of windows putting less pressure on the pool of zeroed pages, when programs want to be extra nice, and tell windows that it can throw away some freed range of memory.

like image 174
doug65536 Avatar answered Oct 21 '22 22:10

doug65536