Le livre Game Coding Complete, Fourth Edition , chapitre 5 ( Game Initialization and Shutdown ), section Checking Memory contient cet exemple de code intéressant:
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;
}
}
Cela soulève quelques questions.
La première partie demande simplement au système d'exploitation (Windows) combien de RAM physique est disponible. La partie curieuse est la deuxième, qui alloue un énorme morceau de mémoire et le libère immédiatement:
char *buff = GCC_NEW char[virtualRAMNeeded];
if (buff)
{
delete[] buff;
}
L'auteur poursuit en expliquant:
... cette fonction alloue et libère immédiatement un énorme bloc de mémoire. Cela a pour effet de faire nettoyer Windows toutes les ordures qui se sont accumulées dans le gestionnaire de mémoire et vérifie que vous pouvez allouer un bloc contigu aussi grand que vous en avez besoin. Si l'appel réussit, vous avez essentiellement exécuté l'équivalent d'une machine Zamboni dans la mémoire de votre système, le préparant pour que votre jeu atteigne la glace ...
Mais j'ai mes réserves là-dessus.
"Nettoyer les déchets qui se sont accumulés dans le gestionnaire de mémoire?" Vraiment? Si le jeu vient de commencer, ne devrait-il pas y avoir d'ordures?
"Vous assurer que vous pouvez allouer un bloc contigu?" Dans le cas très spécifique où vous allez gérer la mémoire vous-même, cela aurait du sens, mais quand même, si vous allouez beaucoup de mémoire dès le départ, vous empêchez pratiquement toute autre application de fonctionner le système pendant que le vôtre est allumé.
De plus, cela ne forcera-t-il pas le système d'exploitation à engager toute cette mémoire et, par conséquent, à expulser beaucoup de mémoire vers l'espace disque d'échange, ce qui ralentira beaucoup le démarrage de votre application?
Est-ce vraiment une bonne pratique?
operator new
pour nullptr
), si vous me le permettez dire. La meilleure chose que vous puissiez faire avec ce livre est d'allumer votre cheminée. Bien entendu, l'allocation et la libération d'un grand bloc de mémoire ne "nettoient" pas la mémoire.
new
opérateur global pour retourner null au lieu de lancer bad_alloc
. S'ils ne l'ont pas fait, alors oui, ce code est encore plus absurde: P
operator delete
est nécessaire de l'accepter nullptr
et de le traiter comme non opérationnel. Toute surcharge globale qui ne fait pas cela est rompue. Ce qui signifie que c'est absurde dans les deux cas. Tout comme en supposant qu'allouer un énorme bloc de mémoire et le libérer fera "magiquement" quelque chose de bien. Au mieux, cela ne fera aucun mal (très probablement, car les pages ne sont même pas touchées ... sinon il peut échanger certaines pages de votre jeu de travail que vous devrez recharger plus tard).