190 likes | 310 Views
Win32 Programming. Lesson 16: Virtual Memory. Where are we?. We’ve covered the theory of Windows memory, and poked around some Now let’s use how to use memory. Three ways to Use Memory. Virtual Memory – Best for very large arrays and structures
E N D
Win32 Programming Lesson 16: Virtual Memory
Where are we? • We’ve covered the theory of Windows memory, and poked around some • Now let’s use how to use memory
Three ways to Use Memory • Virtual Memory – Best for very large arrays and structures • Memory-mapped files – Good for managing data streams and sharing memory between applications • Heaps – Best for managing large numbers of small objects
Reserving Memory • Fairly straightforward: • PVOID VirtualAlloc( PVOID pvAddress, SIZE_T dwSize, DWORD fdwAllocationType, DWORD fdwProtect);
Parameters • pvAddress: Usually NULL, but can be where you would like the memory • dwSize: How much memory you would like • dwAllocationType: Should we RESERVE memory or COMMIT it? • dwProtection: The type of memory protection on this area of memory
Before Use… • Once you have reserved memory, you need to commit it before the pages can be accessed • Same call, but you use the parameters slightly differently • You don’t have to COMMIT all the region – you just need to COMMIT pages • Why is this a Good Thing?
Can do it all in one go… • Can bitwise-OR the flags… • Just like this: • PVOID pvMem = VirtualAlloc( NULL, 99 * 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); • Can also specify MEM_TOP_DOWN
Knowing When to Commit • Let’s say you’re writing a spreadsheet application (gee, there’s a good idea…) • Why doesn’t Excel crash the system when it loads a spreadsheet (well, usually…)
MEM_LARGE_PAGE • New addition to VirtualAlloc • Higher performance, as we can allocate a large page of memory • These pages are not pageable however • SIZE_T GetLargePageMinimum();
Determining the State of an Address • Four ways… • Always call COMMIT – but this is slow because it’s often (usually?) unnecessary • Use VirtualQuery to map the state and commit if necessary • Keep a record of which pages you’ve committed and which you have – can be complicated • Use SEH to catch memory exceptions and COMMIT on error (best way)
Must Decommit • If you don’t want to kill the machine, it’s good to decommit memory • BOOL VirtualFree( LPVOID pvAddress, SIZE_T dwSize, DWORD fdwFreeType); • Pass 0 for dwSize as the system already knows it • Must pass MEM_RELEASE
Knowing when is the trick… • Consider our Spreadsheet example • Make each cell a page (not very practical, but very simple) • Keep track of which cells are on which page • Implement a garbage collection function which checks the state of cells
Bug Hunting… • Sometimes protecting memory can help tremendously when hunting bugs and coding defensively • Can use VirtualProtect to change access when we’re not using memory • If a rogue pointer blats into your memory, you’re protected
Physical Storage • Knowledge of the underlying system can help tremendously when trying to improve performance • For example, imagine you have some memory which you use for short periods of time… • How does the design of the system potentially slow things down?
RESETting Memory • When the system looks to free physical memory it has to write RAM to the paging file • But what if you say that the memory to swap isn’t important? That is, the changes don’t need to be kept? • If you have write-access but the changes aren’t needed you can RESET the memory
Example • PINT pnData = (PINT) VirtualAlloc( NULL, 1024, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); pn[0] = 100; pn[1] = 200; VirtualAlloc( (PVOID) pnData, sizeof(int), MEM_RESET, PAGE_READWRITE);
MEM_RESET • One thing to remember is that the MEM_RESET flag doesn’t work if you OR it with anything else • It only makes sense used on its own
Cool Stuff: AWE • Address Windowing Extensions • Allows the program to access more memory than fits in its process space • Introduced in Windows 2000 • Uses AllocateUserPhysicalPages • Then MAP to a Window: • BOOL MapUserPhysicalPages( PVOID pvAddressWindow, ULONG_PTR ulRAMPages, PULONG_PTR aRAMPages);
Stack Space • Each thread stack exists in the process’ address space • Very clever – assigns a “guard page” so that the system knows when to commit more memory to the stack • When the stack grows too far, generates a EXCEPTION_STACK_OVERFLOW • Can handle via a SEH – we’ll talk about that later in the term