LINUX.ORG.RU

malloc не возвращает NULL


0

0

Доброго времени суток, всемогущий ALL! столкнулся я с такой проблемой, что malloc и иже с ним не возвращает нулевой указатель при отсутствии памяти, а оперционка просто прибивает приложение с криком "памяти нема". Ситуация происходит на ядрах 2.4.* Что делать, куда копать?

anonymous

Например, поставить ограничение на размер виртуальной памяти (ulimit -v).

anonymous
()

Расслабиться и получать удовольствие. Это так и задумывалось и никак не исправишь.

anonymous
()
Ответ на: комментарий от anonymous

Если из-за overcommit, то SIGKILL, который нельзя обрабатывать. Поэтому ставьте себе нормальный лимит на виртуальную память, тогда всё будет хорошо.

anonymous
()

> malloc и иже с ним не возвращает нулевой
> указатель при отсутствии памяти

если памяти нет, malloc() вернет 0. нужно понимать,
что malloc() выделяет виртуальную память. то есть
к тому моменту, когда вы в полученную память пишете
в первый раз, linux пытается найти для нее страничку,
и, если не находит - oom.

иными словами в момент работы malloc() память есть,
а когда вы ее используете - ее уже и нету.

ulimit здесь не поможет. то есть поможет в том смысле,
что malloc() вернет 0 после превышения лимита, но oom
все равно может быть.

это называется overcommit. если такое поведение вам
не нравится - можете его изменить в /proc/sys/vm/overcommit_memory

idle ★★★★★
()
Ответ на: комментарий от idle

> если такое поведение вам не нравится - можете его изменить в /proc/sys/vm/overcommit_memory

Дык не поможет ведь -- была же уже дискуссия по этому поводу. Все равно ядро будет говорить, что память есть, а при попытке ее заюзать отработает OOM-killer.

nobody ★★
()
Ответ на: комментарий от nobody

> Дык не поможет ведь -- была же уже дискуссия по этому поводу.

да помню, с вами же и дискутировали.

действительно, абсолютной гарантии от oom strict
overcommit дать не может. ну не может ядро гарантировать,
что администратор не скажет swapoff. не может оно
также гарантировать, что какой-нибудь драйвер в следующую
секунду не попытается отожрать всю память.

но если такие вот "неожиданные" запросы на память
не будут превышать 100% - sysctl_overcommit_ratio
от доступной памяти, то все работает.

idle ★★★★★
()
Ответ на: комментарий от idle

Хм. Действительно, работает. Дело было так: в новостях (с полгода
назад) прошла инфа, что из 2.4.x выкинули интеллектуальный OOM-killer,
т.е. ядро теперь будет убивать первого, кто попросит памяти. Там же
было про overcommit, и чувак приводил код, который гарантированно
убивает программу. Вот этот код (по памяти):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
  {
  char *ptr = NULL;
  size_t size, incr = atoi(argv[1]) * 1024 * 1024;
  for (size = 0; ; size += incr)
    {
    ptr = realloc(ptr, size + incr);
    if (!ptr)
      {
      perror(NULL);
      return 1;
      }
    printf("%u\n", size + incr);
    memset(ptr + size, 0, incr);
    }
  return 0;
  }

tmp$ gcc a.c
tmp$ ./a.out 100
104857600
209715200
Cannot allocate memory
tmp$ ./a.out 10
10485760
20971520
31457280
41943040
52428800
62914560
73400320
83886080
94371840
104857600
115343360
125829120
136314880
146800640
157286400
167772160
178257920
188743680
199229440
209715200
220200960
230686720
Cannot allocate memory

Так вот, при выделении памяти по 10М ядро гарантированно убивало
процесс -- я сам тогда этот код у себя запускал и проверял. Причем
программа умирала на memset (т.е. после printf). А теперь не убивает!
Прогресс!

Посему автору топика совет: юзать последнюю версию ядра из 2.4.x.
(у меня 2.4.27).

BTW, интеллектуальный OOM-killer таки вернули в ядро, но в виде
опции в "make menuconfig". (у меня оно включено -- хотя это по логике
вещей не должно влиять на приведенный тест, но все-таки...)

nobody ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.