The book Game Coding Complete, Fourth Edition, chapter 5 (Game Initialization and Shutdown), section Checking Memory contains this interesting code sample:
bool CheckMemory(const DWORDLONG physicalRAMNeeded, const DWORDLONG virtualRAMNeeded)
{
MEMORYSTATUSEX status;
GlobalMemoryStatusEx(&status);
if (status.ullTotalPhys < physicalRAMNeeded)
{
// you don’t have enough physical memory. Tell the player to go get a
// real computer and give this one to his mother.
GCC_ERROR("CheckMemory Failure: Not enough physical memory.");
return false;
}
// Check for enough free memory.
if (status.ullAvailVirtual < virtualRAMNeeded)
{
// you don’t have enough virtual memory available.
// Tell the player to shut down the copy of Visual Studio running in the
// background, or whatever seems to be sucking the memory dry.
GCC_ERROR("CheckMemory Failure: Not enough virtual memory.");
return false;
}
char *buff = GCC_NEW char[virtualRAMNeeded];
if (buff)
{
delete[] buff;
}
else
{
// even though there is enough memory, it isn't available in one
// block, which can be critical for games that manage their own memory
GCC_ERROR("CheckMemory Failure: Not enough contiguous memory.");
return false;
}
}
This raises some questions.
The first part just asks the OS (Windows) how much physical RAM is available. The curious part is the second one, which allocates a huge chunk of memory and frees it right away:
char *buff = GCC_NEW char[virtualRAMNeeded];
if (buff)
{
delete[] buff;
}
The author goes on to explain:
... this function allocates and immediately releases a huge block of memory. This has the effect of making Windows clean up any garbage that has accumulated in the memory manager and double-checks that you can allocate a contiguous block as large as you need. If the call succeeds, you've essentially run the equivalent of a Zamboni machine through your system's memory, getting it ready for your game to hit the ice...
But I have my reservations on that.
"Cleaning garbage that has accumulated in the memory manager?" Really? If the game has just started, shouldn't there be no garbage?
"Making sure you can allocate a contiguous block?" In the very specific case where you are going to manage memory yourself, this would them make some sense, but still, if you do allocate a lot of memory right of the bat, you pretty much make it impossible for any other application to run in the system while yours is on.
Also, isn't this likely to force the OS to commit all that memory, and as consequence evict a lot of memory to the swap disk space, slowing your app startup a lot?
Is this really a good practice?
operator new
fornullptr
), if you allow me to say. Best thing you can do with that book is light your chimney. Allocating and freeing a large block of memory of course doesn't "clean up" memory. \$\endgroup\$new
operator to return null instead of throwingbad_alloc
. If they didn't, then yes, this code is even more nonsensical :P \$\endgroup\$operator delete
is required to acceptnullptr
and treat it as no-op. Any global overload that doesn't do that is broken. Which means it's nonsensical either way. Just like assuming that allocating a huge block of memory and releasing it will "magically" do something good. At best, it won't do any harm (most likely, since the pages aren't even touched... otherwise it may swap out some pages from your working set which you'll need to reload later). \$\endgroup\$