Как определяется объем памяти в C ?

#c #memory

#c #память

Вопрос:

Мне интересно узнать, каков лимит памяти для автоматически и динамически распределяемых переменных, поэтому я тестировал подобные вещи:

 int main() {
    const int N = 1000000;
    int a[N];
    a[1] = 100;
}
  

Я обнаружил, что максимальное N, которое не приведет к ошибке сегментации, составляет 2 600 000, около 10 МБ.

Затем я протестировал динамически распределяемые переменные, например:

 int main() {
    const int N = 1000000;
    int* a = new int [N];
    delete[] a;
}
  

Я обнаружил, что максимальное N, которое не будет генерировать исключение, составляет около 730 000 000, то есть около 3 ГБ.

Теперь вопрос в том, как определяется ограничение в 10 МБ (для автоматических переменных) и 3 ГБ (для динамически распределяемых переменных). Я предполагаю, что это связано с моей машиной? Кроме того, есть ли какой-нибудь способ увеличить лимит, если мне это действительно нужно?

Комментарии:

1. 3G — довольно типичный предел для процесса на 32-битном процессоре, другой 1G зарезервирован для аппаратной адресации, ОС и т. Д…

2. @BenVoigt, я видел обсуждение 3 ГБ, но я не обсуждаю 10 МБ, поэтому я задал это как один вопрос.

Ответ №1:

Язык ничего не требует. Все это определяется реализацией.

Автоматические переменные обычно помещаются в стек, и обычно вы можете увеличить максимальный размер с помощью опций компилятора. Свободное хранилище обычно представляет собой кучу и ограничено только используемым адресным пространством. Не рассчитывайте на более чем 2-3 ГБ в 32-разрядной среде, в 64-разрядной среде ограничение будет намного выше. Конечно, вы не сможете выделить все 64-разрядное адресное пространство, вы достигнете предела доступной виртуальной памяти (ОЗУ пространство подкачки).

Ответ №2:

Пределом для автоматических переменных является объем памяти, выделенный для машинного стека. 10 МБ на самом деле довольно много; 1 или 2 МБ — более распространенное значение по умолчанию.

Очевидно, что 3 ГБ — это ограничение ОС — это примерно размер пространства процесса, разрешенного ОС для программы. Он будет сильно различаться в зависимости от ОС и аппаратной платформы.

Комментарии:

1. Вы знаете, где указан предел для автоматической переменной? Или как я могу узнать напрямую, а не тестировать?

2. ulimit -s должен указать вам, сколько байтов вы можете выделить в стеке.

3. @mange : конечно, ulimit на некоторых операционных системах работает хуже, чем на других 🙂 @JohnYang: в Windows значение устанавливается для данного исполняемого файла с /STACK помощью опции компоновщика.

4. @mange Отлично! Это ответ, который я ищу. Знаете ли вы, как его изменить в Linux?

5. ulimit -s NUM изменит ограничение в bash. Однако обратите внимание, что это изменит его только для этого сеанса bash (поэтому все остальные сеансы bash не затрагиваются). Также: выше я имел в виду кбайт, а не байты.

Ответ №3:

Ограничение в 3 ГБ, вероятно, можно исправить, перейдя на 64-разрядную ОС (с большим объемом оперативной памяти).

Существует разумная вероятность (но нет уверенности), что ограничение в 10 МБ может быть скорректировано с помощью некоторых флагов компоновщика.

Комментарии:

1. 32-разрядное приложение может использовать окно просмотра объемом 3 ГБ в гораздо большей области памяти, используя API файлов с отображением памяти.