O livro Game Coding Complete, quarta edição , capítulo 5 ( Inicialização e desligamento do jogo ), seção Verificando memória, contém este interessante exemplo de código:
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;
}
}
Isso levanta algumas questões.
A primeira parte apenas pergunta ao sistema operacional (Windows) quanta RAM física está disponível. A parte curiosa é a segunda, que aloca um grande pedaço de memória e a libera imediatamente:
char *buff = GCC_NEW char[virtualRAMNeeded];
if (buff)
{
delete[] buff;
}
O autor continua explicando:
... essa função aloca e libera imediatamente um enorme bloco de memória. Isso tem o efeito de fazer com que o Windows limpe qualquer lixo acumulado no gerenciador de memória e verifique novamente se você pode alocar um bloco contíguo do tamanho necessário. Se a chamada for bem-sucedida, você basicamente executará o equivalente a uma máquina Zamboni na memória do sistema, preparando-a para o seu jogo atingir o gelo ...
Mas tenho minhas reservas nisso.
"Limpando o lixo acumulado no gerenciador de memória?" Verdade? Se o jogo acabou de começar, não deveria haver lixo?
"Certificando-se de que você pode alocar um bloco contíguo?" No caso muito específico em que você mesmo gerenciará a memória, isso faria algum sentido, mas ainda assim, se você alocar muita memória diretamente do bastão, praticamente impossibilitará a execução de qualquer outro aplicativo o sistema enquanto o seu estiver ligado.
Além disso, não é provável que isso force o sistema operacional a comprometer toda essa memória e, como consequência, despeje muita memória no espaço em disco de troca, retardando muito a inicialização do aplicativo?
Esta é realmente uma boa prática?
operator new
para nullptr
), se me permite dizer. A melhor coisa que você pode fazer com esse livro é acender sua chaminé. Alocar e liberar um grande bloco de memória, é claro , não "limpa" a memória.
new
operador global para retornar nulo em vez de jogar bad_alloc
. Se não, então sim, esse código é ainda mais absurdo: P
operator delete
é necessário aceitá-lo nullptr
e tratá-lo como não operacional. Qualquer sobrecarga global que não faz isso é interrompida. O que significa que é absurdo de qualquer maneira. Assim como assumir que alocar um enorme bloco de memória e liberá-lo "magicamente" fará algo bom. Na melhor das hipóteses, não causará nenhum dano (provavelmente, uma vez que as páginas nem sequer são tocadas ... caso contrário, poderá trocar algumas páginas do seu conjunto de trabalho que você precisará recarregar mais tarde).