Почему в современном Linux размер стека по умолчанию такой огромный - 8 МБ (даже 10 в некоторых дистрибутивах)

10

Например, на OSX это даже меньше, чем 512k.

Есть ли рекомендуемый размер, учитывая, что приложение не использует рекурсию и не выделяет много переменных стека ?
Я знаю, что вопрос слишком широкий и сильно зависит от использования, но все же хотел спросить, так как мне было интересно, есть ли какая-то скрытая / внутренняя / системная причина этого огромного числа.


Мне было интересно, так как я намерен изменить размер стека на 512 КиБ в моем приложении - это все равно звучит как огромное количество для этого, но это намного меньше, чем 8 МБ - и приведет к значительному уменьшению виртуальной памяти процесса, так как я есть много потоков (I / O).

Я также знаю, что это не очень больно, хорошо объяснил здесь : размер стека по умолчанию для pthreads

Кирилл Киров
источник
Вы используете 32-битный процессор? Процессоры X86_64 предлагают виртуальное адресное пространство до 128 терабайт (в пространстве пользователя), которого должно хватить для стеков 8 МБ.
Йохан Мирен
@ JohanMyréen - нет, x64 это так. Это не имеет большого значения, мне просто интересно, нет реальной причины делать это (на данный момент).
Кирилл Киров
В 2019 и 8 МиБ много памяти? Я так не думаю. Большой размер стека по умолчанию позволяет очень легко писать программы с рекурсией. Я был очень удивлен, узнав, что размер стека по умолчанию в Windows составляет всего 1 МБ!
oldherl

Ответы:

15

Как уже говорили другие, и как упоминается в ссылке, которую вы предоставляете в своем вопросе, наличие стека 8 МБ ничего не повредит (кроме использования адресного пространства - в 64-битной системе это не имеет значения).

Linux использует стеки по 8 МБ в течение очень долгого времени; изменение было введено в версии ядра 1.3.7 в июле 1995 года. Тогда оно было представлено как вводящее ограничение, ранее его не было:

Ограничьте стек до некоторого нормального значения по умолчанию: root всегда может увеличить этот предел, если это необходимо. 8 МБ кажется разумным.

В Linux ограничение стека также влияет на размер программных аргументов и среды, которые ограничены одной четвертой предела стека ; ядро применяет минимум 32 страницы для аргументов и среды.

Для потоков, если лимит стека ( RLIMIT_STACK) не ограничен, pthread_createприменяет свои собственные ограничения к стекам новых потоков - и на большинстве архитектур это меньше 8 МБ.

Стивен Китт
источник
1
Вау, интересно. Я думал, что это было недавно введено. У меня есть около 200 потоков (это еще одна длинная тема, поэтому давайте просто проигнорируем это на данный момент) и topпоказывает страшные результаты VIRT. Хотя, копая немного глубже, большая часть этого виртуального адресного пространства берется из каждого потока (памяти), а не из размера стека, поэтому уменьшение размера стека не приведет к значительному сокращению виртуальной памяти. Мне было просто любопытно, почему 8MiB и почему так много.
Кирилл Киров
«8 МБ» означает, что стек каждого потока может увеличиться до 8 МБ, если поток решит его использовать. Но физическая память не будет выделена, пока память не будет фактически использована. Если ваши 200 потоков используют 512 КБ каждый, вы будете использовать физическую память 100 МБ, а не 1,6 ГБ.
Гунтрам Блом поддерживает Монику
Если вы не меняете местами, то столбец RES topдает вам гораздо лучший ответ на вопрос «какую память использует этот процесс», чем VIRT.
kbolino
1
@Guntram ОП хорошо знает об этом, смотрите ссылку в вопросе.
Стивен Китт
1

8 МБ - это виртуальный размер стека. Ошибка страницы произойдет, когда ваше приложение попытается использовать больше стека, чем физически выделено в данный момент. Затем обработчик ошибок страницы ядра выделит физическую страницу, а затем ваше приложение продолжит работу.

См. Https://unix.stackexchange.com/a/280865/21212 для полного объяснения.

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

Колин т Харт
источник
1
Я уже связал этот ответ в своем вопросе. Я также написал, что я знаю об этом, но это на самом деле не отвечает на вопрос. В любом случае спасибо
Кирилл Киров
Я думаю, что вам нужно пересмотреть предпосылки вопроса, и этот (не) ответ указывает на причину. Виртуальная память не является реальной памятью. Размер стека может составлять 800 МБ, и это не повлияет на фактическое использование памяти, если ваше приложение не создает фреймы стека более чем на 8 МБ.
kbolino