2013-07-06 2 views
1

Этот интересный код всегда выделяет 3 ГБ памяти в системах Linux, даже если физическая память составляет менее 3 ГБ.Почему это странное поведение распределения памяти

Как? (У меня есть 2,7 Гб оперативной памяти в моей системе, и этот код выделяется 3.054 MB памяти!)

#include <stdio.h> 
    #include <string.h> 
    #include <stdlib.h> 
    int main(int argc, char *argv[]) 
    { 
     void *ptr; 
     int n = 0; 
     while (1) { 
      // Allocate in 1 MB chunks 
      ptr = malloc(0x100000); 
      // Stop when we can't allocate any more 
      if (ptr == NULL) 
       break; 
      n++; 
     } 
     // How much did we get? 
     printf("malloced %d MB\n", n); 
     pause(); 
    } 
+0

У вас есть файл/раздел подкачки? – user2422531

+0

@ user2422531: У меня был, но я отключил своп, и все равно получаю тот же результат. – Inquisitive

+0

Ищите термин «виртуальная память» в сети под ОС. – 0decimal0

ответ

1

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

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
int main(int argc, char *argv[]) 
{ 
    char *ptr; 
    int n = 0; 
    while (1) { 
     // Allocate in 4kb chunks 
     ptr = malloc(0x1000); 
     // Stop when we can't allocate any more 
     if (ptr == NULL) 
      break; 
     *ptr = 1; // modify one byte on the page 
     n++; 
    } 
    // How much did we get? 
    printf("malloced %d MB\n", n/256); 
    pause(); 
} 

Если у вас есть достаточно подкачки, но недостаточно оперативной памяти, то этот код начнет обмолота файла подкачки тяжело. Если у вас недостаточно обмена, это может привести к сбою до того, как он достигнет цели.

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

  • совокупный объем оперативной памяти и диска выделяется для замены
  • Размер виртуального адресного пространства ограничивает
  • ресурсов, налагаемые ulimit

В 32-разрядной версии Linux операционная система предоставляет каждому виртуальному адресному пространству 3GB для каждой задачи. В 64-разрядной версии Linux я считаю, что число находится в 100 с терабайт. Я не уверен, что по умолчанию ulimit. Итак, найдите 64-битную систему и попробуйте модифицированную программу. Я думаю, что ты будешь в долгую ночь. ;-)

Edit: Здесь используется по умолчанию ulimit значения на моем 64-битной Ubuntu 11.04 системы:

$ ulimit -a 
core file size   (blocks, -c) 0 
data seg size   (kbytes, -d) unlimited 
scheduling priority    (-e) 20 
file size    (blocks, -f) unlimited 
pending signals     (-i) 16382 
max locked memory  (kbytes, -l) 64 
max memory size   (kbytes, -m) unlimited 
open files      (-n) 1024 
pipe size   (512 bytes, -p) 8 
POSIX message queues  (bytes, -q) 819200 
real-time priority    (-r) 0 
stack size    (kbytes, -s) 8192 
cpu time    (seconds, -t) unlimited 
max user processes    (-u) unlimited 
virtual memory   (kbytes, -v) unlimited 
file locks      (-x) unlimited 

Таким образом, оказывается, что не существует ограничение на размер памяти по умолчанию для задачи.

2

Когда машины работают из физической памяти для решения они могут использовать пространство на жестком диске «действовать в качестве оперативной памяти». Это ЗНАЧИТЕЛЬНО СЛЕВА, но все еще можно сделать.

В целом существует несколько уровней, что машина может использовать для доступа к информации:

  1. Cache (быстрый)
  2. RAM
  3. Жесткий диск (медленный)

Это будет используйте самые быстрые, когда они доступны, но, как вы указывали, иногда нужно использовать другие ресурсы.

Смежные вопросы