10

次のプログラムは、メモリが不足するとカーネルによって強制終了されます。グローバル変数をいつ「ENOMEM」に割り当てる必要があるかを知りたいです。

#define MEGABYTE 1024*1024
#define TRUE 1
int main(int argc, char *argv[]){

    void *myblock = NULL;
    int count = 0;

    while(TRUE)
    {
            myblock = (void *) malloc(MEGABYTE);
            if (!myblock) break;
            memset(myblock,1, MEGABYTE);
            printf("Currently allocating %d MB\n",++count);
    }
    exit(0);
}
4

4 に答える 4

6

まず、オーバーコミットしないようにカーネルを修正します。

echo "2" > /proc/sys/vm/overcommit_memory

これmallocで適切に動作するはずです。

于 2012-06-10T03:16:55.597 に答える
5

一度に大量のメモリを割り当てようとすると発生します。

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

int main(int argc, char *argv[])
{
  void *p;

  p = malloc(1024L * 1024 * 1024 * 1024);
  if(p == NULL)
  {
    printf("%d\n", errno);
    perror("malloc");
  }
}

あなたの場合、OOMキラーは最初にプロセスに到達しています。

于 2012-06-10T03:17:39.403 に答える
5

「R」が示唆したように、問題は「オーバーコミット」である Linux メモリ管理のデフォルトの動作です。これは、カーネルがメモリを正常に割り当てたと主張しているが、後でアクセスしようとするまで実際にはメモリを割り当てないことを意味します。カーネルは、割り当てられたメモリが多すぎることを検出すると、「OOM (メモリ不足) キラー」を使用してプロセスを強制終了し、メモリを解放します。強制終了するプロセスを選択する方法は複雑ですが、システム内のメモリの大部分を割り当てたばかりの場合、弾丸を取得するのはおそらくプロセスになります。

これがおかしいと思うなら、同意する人もいるでしょう。

Rが言ったように、期待どおりに動作させるには:

echo "2" > /proc/sys/vm/overcommit_memory

于 2012-06-10T05:46:16.277 に答える
3

errnoに設定されると思いますENOMEM

で定義されたマクロstdio.h。これがドキュメントです。

#define ENOMEM          12      /* Out of Memory */

このステートメントで malloc を呼び出した後:

myblock = (void *) malloc(MEGABYTE);

そして、関数はNULL- システムがメモリ不足であるため - を返します。

このSOの質問は非常に興味深いものでした。

それが役に立てば幸い!

于 2012-06-10T03:19:13.307 に答える