malloc ведет себя по-разному на разных машинах - PullRequest
5 голосов
/ 01 февраля 2010

Я вижу совершенно другое поведение при запуске программы, которая пытается превысить RSS на разных машинах. Код выглядит примерно так:

...
  char** s = (char**)malloc(10000*sizeof(char*));

  for (i = 0; i < 10000; i++){
    s[i] = (char*)malloc(1000*1000*sizeof(char));
    if (s[i] == NULL) {
      printf("cannot allocate memory for s[%d]",i);
      exit(1);
    }
  }

  int j = 0;
  while(1){
    for (i = 0; i < 10000; i++){
      for (j = 0; j < 1000*1000; j++) {
        s[i][j] = 1;
      }
      if ((i % 100) == 0) printf("i = %d\n", i);
    }
  }
  for (i = 0; i < 10000; i++)
    free(s[i]);
  free(s);
...

Приведенный выше код пытается выделить около 10 ГБ памяти с помощью malloc. Первые две машины, на которых я пробовал этот код, работали на ядре Linux 2.6, а последняя - на ядре Linux 2.4. Вот поведение, которое я вижу на этих машинах:

Machine1: память выделяется с использованием избыточной памяти, но при назначении значений местам памяти в цикле while она выделяет столько, сколько позволяет RSS. Таким образом, OOM Killer убивает процесс, когда печатается i = 3800, что составляет около 4 ГБ памяти на этом аппарате.

Machine2: память выделяется с использованием избыточной памяти, и цикл while продолжается вечно, выделяя страницы из виртуальной памяти. Процесс идет немного медленнее после печати i = 3800, что нормально.

machine3: эта машина имеет только 2 ГБ памяти. Память не может быть даже выделена. Похоже, что over commit не установлен или ядро ​​2.4 не поддерживает выделение страниц виртуальной машины с помощью malloc! Таким образом, в первом цикле for он выходит при выделении памяти для i = 2138

Мое желаемое действие - это то, что происходит в машине2. Кто-нибудь знает, какие параметры (ядра?) Должны быть установлены, чтобы ОС могла распределять страницы виртуальной памяти с помощью malloc и запускать подкачку, когда требуемая память превышает RSS?

Спасибо

1 Ответ

5 голосов
/ 01 февраля 2010

Вы не сможете выделить 100 ГБ на 32-разрядной машине и обращаться к ней с помощью обычных указателей, что, по-видимому, и использует ваш код. Тот факт, что машина 1 завершает процесс, когда он занимает примерно 4 ГБ, а машина 2 не сильно свидетельствует о том, что машина 2 работает под управлением 64-разрядной ОС.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...