как исчерпать память? - PullRequest
4 голосов
/ 07 июля 2011

Это может выглядеть глупо, но сейчас я немного растерялся.Почему эта программа не потребляет всю память?Например: у меня в терминале Linux (2G RAM) работает следующая программа,

  #include <iostream>
  #include <cmath>
  using namespace std;

  int main()
  {
     cout<<sizeof(int*)<<endl;
     for(int i=0; i<pow(2.0,30.0);i++)
       {
         new int(i);
       }
    return 1;
  }

1) Я подтвердил, что размер int на этой машине составляет 4 байта, тогда для оперативной памяти 2 ГБ он может содержать2 ^ 30/2 ^ 2 = 2 ^ 28

2) следуя приведенной выше логике, как можно изменить программу, фактически занимающую всю память 2 ГБ?

Добавлено: Я просто хочууверен, что я правильно понимаю, теоретически.Если нет виртуальной памяти или оптимизации ОС и т. Д., Только 2GBRAM может содержать 2 ^ 28 int, это так?В таком случае вышеуказанная программа будет использовать всю память?Знаете ли вы, как я мог отключить функции виртуальной памяти / подкачки и т. Д. В Linux?

Спасибо!

Ответы [ 5 ]

7 голосов
/ 07 июля 2011

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

Ваш фактический предел - это адресное пространство указателя,который, если вы не компилируете (и не используете) 64-битную платформу, является 32-битным.Таким образом, вы можете выделить 4 ГБ пространства.

4 голосов
/ 07 июля 2011

Ваши расчеты кажутся подозрительными.

2 20 = 1 048 576
2 11 = 2048

Чтобы выделить миллиард целых чисел, попробуйте 2 30 . Обратите внимание, что ваш vector<int*> займет значительное количество места (по крайней мере, столько же, сколько целые числа, которые вы выделяете). Чтобы просто исчерпать память, вам это совсем не нужно. Вы можете вызвать new int(i) и выбросить возвращенный указатель, и память все равно будет выделена.

Помните также, что ваша машина, вероятно, имеет виртуальную память, превышающую установленную физическую память объемом 2 ГБ.

1 голос
/ 07 июля 2011

Ваша программа не делает ничего полезного со своей памятью.Поэтому оптимизатор может оптимизировать его до:

  #include <iostream>

  int main()
  {
     std::cout<<sizeof(int*)<<endl;
     for(int i=0; i<(1<<10);i++)
       {
         // nothing
       }
    return 1;
  }
0 голосов
/ 07 июля 2011

Существует некоторое неправильное представление об использовании памяти.

  1. 2 ГБ памяти не означает, что вы можете использовать только 2 ГБ памяти. (1) у нас есть пространство подкачки; (2) Linux перегружен.

  2. new int не занимает 4 байта. Есть накладные расходы памяти

  3. Вы не можете использовать всю память. Фрагментация памяти, секция .text и т. Д. Занимают место в памяти.

0 голосов
/ 07 июля 2011

2 ГБ - это два миллиарда байтов. Это означает, что ваша оперативная память может содержать около 500 миллионов int-указателей. Теперь в вашей системе также есть файл подкачки для хранения, который, вероятно, равен размеру вашей оперативной памяти или больше.

2 ^ 20 - это около миллиона. Таким образом, хотя ваша программа пожирает часть вашей памяти, она не использует ее полностью. Просто увеличьте значение pow () до смехотворно большого числа, и оно будет работать. Веселись!

Также: нет гарантии, что sizeof (int) == sizeof (int *), хотя это верно для многих систем.

...