ブックコンプリート、第4版コーディングゲーム、第5章(ゲームの初期化およびシャットダウン)、セクションのメモリーをチェックするには、この興味深いコードサンプルが含まれています。
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;
}
}
これはいくつかの質問を提起します。
最初の部分は、OS(Windows)に使用可能な物理RAMの量を尋ねるだけです。好奇心が強い部分は2番目の部分で、メモリの巨大なチャンクを割り当ててすぐに解放します。
char *buff = GCC_NEW char[virtualRAMNeeded];
if (buff)
{
delete[] buff;
}
著者は続けて説明します:
...この関数は、巨大なメモリブロックを割り当ててすぐに解放します。これにより、Windowsがメモリマネージャーに蓄積されたガベージをクリーンアップし、必要に応じて連続したブロックを割り当てることができるダブルチェックを行うことができます。呼び出しが成功すると、基本的にシステムのメモリを介してZamboniマシンに相当するものを実行し、ゲームが氷にぶつかる準備を整えます...
しかし、私はそれに留保しています。
「メモリマネージャに蓄積されたガベージをクリーニングしますか?」本当に?ゲームが始まったばかりの場合、ゴミはありませんか?
「連続したブロックを割り当てることができますか?」あなたが自分でメモリを管理しようとする非常に特殊なケースでは、これは理にかなっていますが、バットのすぐ右側に多くのメモリを割り当てると、他のアプリケーションを実行することはほとんど不可能になりますあなたのものがオンの間にシステム。
また、これによりOSがそのすべてのメモリをコミットするように強制され、結果としてスワップディスク領域に大量のメモリが追い出され、アプリの起動が大幅に遅くなることはありませんか?
これは本当に良い習慣ですか?
operator new
for の結果を確認しnullptr
ます)。言う。その本でできることは、煙突を軽くすることです。もちろん、メモリの大きなブロックを割り当てて解放しても、メモリは「クリーンアップ」されません。
new
スローする代わりにnullを返すようにグローバル演算子をオーバーロードしたと思われますbad_alloc
。そうでない場合、はい、このコードはさらに無意味です:P
operator delete
受け入れnullptr
て扱う必要があります。それをしないグローバルなオーバーロードは壊れています。つまり、どちらの方法でも無意味です。巨大なメモリブロックを割り当てて解放すると、「魔法のように」何か良いことができると仮定するのと同じです。せいぜい、それは何の害も与えません(おそらく、ページが触れられないので...そうでなければ、後でリロードする必要がある作業セットからいくつかのページをスワップアウトするかもしれません)。