Unixサーバーでメモリ不足(OOM)の状況をシミュレートするプログラムを作成したいと思います。私はこの超シンプルなメモリイーターを作成しました:
#include <stdio.h>
#include <stdlib.h>
unsigned long long memory_to_eat = 1024 * 50000;
size_t eaten_memory = 0;
void *memory = NULL;
int eat_kilobyte()
{
memory = realloc(memory, (eaten_memory * 1024) + 1024);
if (memory == NULL)
{
// realloc failed here - we probably can't allocate more memory for whatever reason
return 1;
}
else
{
eaten_memory++;
return 0;
}
}
int main(int argc, char **argv)
{
printf("I will try to eat %i kb of ram\n", memory_to_eat);
int megabyte = 0;
while (memory_to_eat > 0)
{
memory_to_eat--;
if (eat_kilobyte())
{
printf("Failed to allocate more memory! Stucked at %i kb :(\n", eaten_memory);
return 200;
}
if (megabyte++ >= 1024)
{
printf("Eaten 1 MB of ram\n");
megabyte = 0;
}
}
printf("Successfully eaten requested memory!\n");
free(memory);
return 0;
}
それは定義されmemory_to_eat
たのと同じだけのメモリを消費しますが、現在はちょうど50 GBのRAMです。メモリを1 MBずつ割り当て、それ以上割り当てられなかったポイントを正確に出力するので、どの最大値を取得できたかがわかります。
問題は、それが機能することです。物理メモリが1 GBのシステムでも。
topを確認すると、プロセスが50 GBの仮想メモリを消費し、常駐メモリは1 MB未満であることがわかります。本当にそれを消費するメモリイーターを作成する方法はありますか?
システム仕様:Linuxカーネル3.16(Debian)は、ほとんどの場合、オーバーコミットが有効になっていて(チェックアウトの方法がわからない)、スワップなしで仮想化されています。
sysctl -w vm.overcommit_memory=2
ルートとして実行すると、元のプログラムは期待どおりに動作します。mjmwired.net/kernel/Documentation/vm/overcommit-accountingを参照してください。これが他の結果をもたらすかもしれないことに注意してください。特に、非常に大きなプログラム(Webブラウザなど)は、ヘルパープログラム(PDFリーダーなど)の起動に失敗する可能性があります。