Malloc выделяет память больше, чем RAM - PullRequest
5 голосов
/ 21 сентября 2011

Я только что выполнил программу, которая выделяет 13 МБ на машине с 12 МБ (QEMU Emulated!).Не только это, я даже просмотрел память и заполнил ерунду в ней ...

void 
large_mem(void) 
{
  #define LONGMEM  13631488
  long long *ptr = (long long *)malloc(LONGMEM);
  long long i;
  if(!ptr) {
     printf("%s(): array allocation of size %lld failed.\n",__func__,LONGMEM);
     ASSERT(0);
  }
  for(i = 0 ; i < LONGMEM ; i++ ) { 
    *(ptr+i)=i;
  }
  free(ptr);
}

Как это возможно?Я ожидал ошибки сегментации.

Ответы [ 4 ]

10 голосов
/ 21 сентября 2011

Это называется виртуальная память , которая выделена для вашей программы.Это не реальная память, которую вы называете ОЗУ.

Существует также максимальный предел для виртуальной памяти, но он выше, чем ОЗУ.Это реализовано (и определено) вашей операционной системой.

7 голосов
/ 21 сентября 2011

Это называется Lazy Allocation.

Большинство ОС, таких как Linux, имеют модель памяти Lazy Allocation, в которой возвращаемый адрес памяти является виртуальным адресом, а фактическое выделение происходит только во время доступа.ОС предполагает, что она сможет обеспечить это распределение во время доступа.

Память, выделенная malloc , не поддерживается реальной памятью, пока программа не коснется ее.

Хотя, так как calloc инициализирует память до 0, вы можете быть уверены, что ОС уже поддержала выделение памяти с помощью фактической оперативной памяти (или подкачки).

Попробуйте использовать calloc и, скорее всего, он вернет вас из памяти, если ваш файл / раздел подкачки не будет достаточно большим, чтобы удовлетворить запрос.

4 голосов
/ 21 сентября 2011

Похоже, ваша операционная система меняет страницы :

Пейджинг является важной частью реализации виртуальной памяти в большинстве современных операционных систем общего назначения, позволяя им использовать дискхранилище для данных, которые не помещаются в физическую оперативную память (ОЗУ).

Другими словами, операционная система использует часть пространства на жестком диске для удовлетворения вашего запроса на выделение 13 МБ (прибольшой расход скорости, так как жесткий диск намного, намного медленнее , чем RAM).

2 голосов
/ 21 сентября 2011

Если виртуализированная ОС не имеет подкачки, то, с чем вы сталкиваетесь, называется overcommit , и это в основном существует, потому что простой способ управлять ресурсами в системе с виртуальной памятью и запросом / копированием по Писать страницы не значит управлять ими. Overcommit очень похож на то, что банк ссужает больше денег, чем на самом деле - кажется, он работает какое-то время, а потом все рушится. Первое, что вы должны сделать при настройке системы Linux, это исправить командой:

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

Это влияет только на работающее в данный момент ядро; Вы можете сделать его постоянным, добавив строку к /etc/sysctl.conf:

vm.overcommit_memory=2
...