Virtual Memory API and all the cool stuff you can do with it
Chronicles of Memory Management - Part 13
Last time I talked about Virtual Addressing and all the interesting stuff that come with it. I guess it shan’t come as a surprise that there’s an actual API that allows you to work with it directy - Virtual Memory API.
As usual, the infographic goes first and then some additional thoughts. Enjoy!
I hope you found that useful! If not - reach out my complaints mailbox, eh :)
So here’s the deal - Virtual Memory API represents the lowest-level API your process can interact with in order to allocate memory. But here’s a kicker - at that level, you can’t really ask for BYTES. I mean, technically you CAN, but what you will get back are PAGES. E.g. if you ask for 10 bytes - you will get 4096 bytes back (i.e. a single page). If you ask for 10.000 bytes you will get 3 pages back, etc.
Here’s an example:
PMEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
// Ask for 10 bytes
LPVOID memory = VirtualAlloc(nullptr, 10, MEM_COMMIT, PAGE_READWRITE);
VirtualQuery(memory, mbi, sizeof(*mbi));
// mbi.RegionSize will report 4096 bytes
As you can imagine, given that HeapAlloc() and others call VirtualAlloc(), that means that they have to do some book-keeping in order to deal with pages properly. But that’s a different story for another time.
Anyway here are some cool things that VirtualAlloc() allows you to do:
Reserve memory -- which is a really nifty process completely made possible by the fact that OS uses Virtual Addressing instead of physical one. By "reserving" range of memory, you are effectively telling your system that the range of pages you are asking for SHOULD NOT be given to anyone else (i.e. any "new" and "HeapAllocs()" won't get those addresses). This operation does NOTHING to Physical RAM, and it's 100% logical (i.e. all of this happens on the OS' memory manager level) and as such is pretty cheap to do.
Here’s an example:
As you can see - I asked for total of 1GB and 10 Megs, but what’s really committed is just 10 Megs.
Protect Memory -- which if you are thinking in OOP terms would be similar to defining a constant or a private property. You can really set some cool properties on memory pages (e.g. make memory read-only, or completely disable any access) and, for example, ensure that no malicious code can actually do anything nasty. Check out official docs for list of all Memory Protection constatns.
Lock Memory -- which pretty much means to tell OS not to move your bits from RAM to Hard Disk. And this is really cool because getting your bits back from Hard Drive actually bears some cost and hurts efficiency, so asking for your bits to always stay in physical RAM ensures maximum performance. On the other hand this makes your program pretty greedy so you really have to strike a balance here.
You can check the official docs for list of all interesting things you could do.
And that’d be about it for today :) Next time we're going to talk about comparison of various allocation functions.
I also want to emphasize that, as announced before, I started creating graphics on the CLR topic so that's coming out next week as well!
Until then, if you enjoyed this article or learned anything new - I’d appreciate if you share it with your network!
Thanks for reading!
Other articles from the C++ Memory Management series: