-1

このルーチンを使用して、未使用の RAM をゼロで埋めます。一部のコンピューターでクラッシュが発生し、粗いサイズ = サイズ - (サイズ /10); 未使用の RAM の量をゼロで埋めるより正確な方法はありますか?

DWORDLONG getTotalSystemMemory(){
    PROCESS_MEMORY_COUNTERS lMemInfo;
    BOOL success = GetProcessMemoryInfo(
        GetCurrentProcess(),
        &lMemInfo,
        sizeof(lMemInfo)
    ); 
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof(statex);
    GlobalMemoryStatusEx(&statex);
    wprintf(L"Mem: %d\n", lMemInfo.WorkingSetSize);
    return statex.ullAvailPhys - lMemInfo.WorkingSetSize;
}

void Zero(){
    int size =  getTotalSystemMemory();//-(1024*140000)
    size =  size - (size /10);
    //if(size>1073741824) size=1073741824; //2^32-1
    wprintf(L"Mem: %d\n", size);
    BYTE* ar = new BYTE[size];
    RtlSecureZeroMemory(ar,size);
    delete[] ar;
}
4

1 に答える 1

5

このプログラムは、あなたが思っていることをしません。実際、それは逆効果です。幸いなことに、それも不要です。

まず第一に、プログラムは不必要です。Windowsには、空きページをゼロにするためのスレッド全体の唯一の仕事がすでにあります。これは、創造性を欠いてゼロページスレッドとして知られています。このブログエントリでは、その仕組みについてかなり詳しく説明しています。したがって、空きメモリをゼロで埋める方法は、空きメモリをゼロで埋める人がすでにいるため、何もしないことです。

第2に、アプリケーションがメモリを割り当てるとき、カーネルはメモリをアプリケーションに渡す前にメモリがゼロでいっぱいであることを確認するため、プログラムは思ったとおりに動作しません。(事前にゼロ化されたページが十分にない場合、カーネルはその場でページをゼロ化します。)したがって、ゼロを書き出すプログラムは、ゼロの上にゼロを書き込むだけです。

第三に、プログラムは空きメモリに制限されていないため、逆効果です。ビジーであった可能性のあるメモリの大きなチャンクをゼロにします。これにより、他のアプリケーションがアクティブなメモリを放棄して、それをあなたに与えることができるようになる可能性があります。

このプログラムは、空きメモリを取得することしかできなくても、メモリを解放する前に(ゼロを書き込むことによって)メモリを汚すため、逆効果にもなります。ダーティページをカーネルに戻すと、それらは「ダーティ空きメモリ」リストに追加されます。つまり、ゼロページスレッドを実行して、再度ゼロにする必要があります。(この場合、冗長になりますが、カーネルは、解放されたページがゼロでいっぱいかどうかをゼロにする前にわざわざチェックしません。ページがゼロでいっぱいかどうかをチェックするのは、とにかくゼロにするのと同じくらい費用がかかります。)

プログラムの目的が明確ではありません。空きメモリがゼロでいっぱいであるかどうかが重要なのはなぜですか?

于 2013-01-06T13:05:05.387 に答える