Как узнать размер стека c
Перейти к содержимому

Как узнать размер стека c

  • автор:

/F (Задать размер стека)

Без этого параметра размер стека по умолчанию по умолчанию — 1 МБ. Аргумент number может находиться в десятичной или C-языковой нотации. Аргумент может варьироваться от 1 до максимального размера стека, принятого компоновщиком. Компоновщик округляет указанное значение до ближайшего кратного 4 байта. Пространство между /F и number является необязательным.

Возможно, потребуется увеличить размер стека, если программа получает сообщения стека переполнения во время выполнения.

Вы также можете задать размер стека следующими способами:

  • /STACK Использование параметра компоновщика. Дополнительные сведения см. в разделе /STACK (Выделение стека).
  • Использование EDI ТБ IN в ФАЙЛЕ EXE. Дополнительные сведения см. в справочнике по EDI ТБ IN.

Установка данного параметра компилятора в среде разработки Visual Studio

  1. Откройте диалоговое окно Страницы свойств проекта. Подробнее см. в статье Настройка компилятора C++ и свойства сборки в Visual Studio.
  2. Перейдите на страницу свойств Свойства конфигурации>C/C++>Командная строка.
  3. Введите параметр компилятора в поле «Дополнительные параметры «.

Установка данного параметра компилятора программным способом

  • См. раздел AdditionalOptions.

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

Работаю над оптимизацией кода, и столкнулся в ходе оптимизации с переполнением стека. И ситуация такова, что даже вызов procces.nextTick является дорогим, и его приходится вызывать как можно реже. В связи с чем пришлось пока поставить счетчик и сбрасывать стек с помощью procces.nextTick каждый 1000 раз. Сами понимаете, что это такое себе. Поэтому идеально знать текущий размер стека, чтобы обрубать его при, допустим, 95% заполнении.

Отслеживать
13.7k 12 12 золотых знаков 43 43 серебряных знака 75 75 бронзовых знаков
задан 25 мар 2019 в 17:13
163 8 8 бронзовых знаков

Если возникла беда с переполнением стека, то проблема, скорее всего, в неверной логике, и в первую очередь следует её пересмотреть.

26 мар 2019 в 5:50

Проблемы в логике нет, ситуация такова: что нужно парсить гиговые логи, с крошечными записями. Изначально было 1.25 миллиона вызовов чтения fs.read на ГБ лога. Я снял 95% нагрузки на CPU созданием функции кеширования, но теперь может вызваться туча callback’ов подряд без разрыва стека и тем самым вызывать переполнение стека. Подгадать параметры кеша и тд. это не лучшее решение: что если код измениться, расшириться? Файл лога будет иной? Учитывая дороговизну process.nextTick(), было бы полезно к примеру иметь что-то подобное: getStackTrace() из JAVA.

26 мар 2019 в 15:01

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

var arrayContains = Array.prototype.indexOf ? function(arr, val) < return arr.indexOf(val) >-1; > : function(arr, val) < for (var i = 0, len = arr.length; i < len; ++i) < if (arr[i] === val) < return true; >> return false; >; function getCallStackSize() < var count = 0, fn = arguments.callee, functionsSeen = [fn]; while ( (fn = fn.caller) && !arrayContains(functionsSeen, fn) ) < functionsSeen.push(fn); count++; >return count; > 

Отслеживать
ответ дан 25 мар 2019 в 22:13
perfect-elk perfect-elk
26 2 2 бронзовых знака

Суть интересная, но не работоспособная к сожалению. В редких случаях можно получить более менее приблизительный результат, но не более. В связи с тем, что функция будучи в рекурсии, ссылается сама на себя «.caller», нельзя узнать кто вызвал её, предшествуя перед рекурсией. А вне рекурсии нет смысла знать кол-во в стеке, ибо не достижимо. Если бы даже это и работало, была бы где нибудь ниша в отладке, но не в реальной рабочей рекурсии, ибо про производительность только молчать. Информации наскрести не выходит, совсем. Уже даже задумываюсь об перекомпиляции nodejs с доступом к счётчику ~_~

Размер стека потока

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

Лучше выбрать как можно меньший размер стека и зафиксировать стек, необходимый для надежной работы потока или волокна. Каждая страница, зарезервированная для стека, не может использоваться для каких-либо других целей.

Стек освобождается при выходе из потока. Он не освобождается, если поток завершается другим потоком.

Размер зарезервированной и первоначально зафиксированной памяти стека по умолчанию указывается в заголовке исполняемого файла. Создание потока или волокна завершается сбоем, если недостаточно памяти для резервирования или фиксации запрошенного количества байтов. Размер резервирования стека по умолчанию, используемый компоновщиком, составляет 1 МБ. Чтобы указать другой размер резервирования стека по умолчанию для всех потоков и волокон, используйте инструкцию STACKSIZE в файле определения модуля (DEF). Операционная система округляет указанный размер до ближайшего значения, кратного степени детализации распределения в системе (обычно 64 КБ). Чтобы получить степень детализации выделения текущей системы, используйте функцию GetSystemInfo .

Чтобы изменить изначально зафиксированное пространство стека, используйте параметр dwStackSize функции CreateThread, CreateRemoteThread или CreateFiber . Это значение округляется до ближайшей страницы. Как правило, резервный размер — это размер резерва по умолчанию, указанный в заголовке исполняемого файла. Однако если изначально зафиксированный размер, заданный dwStackSize , больше или равен размеру резерва по умолчанию, размер резерва — это новый размер фиксации, округленный до ближайшего, кратного 1 МБ.

Чтобы изменить размер зарезервированного стека, задайте параметру dwCreationFlagscreateThread или CreateRemoteThread значение STACK_SIZE_PARAM_IS_A_RESERVATION и используйте параметр dwStackSize . В этом случае изначально зафиксированный размер является размером по умолчанию, указанным в заголовке исполняемого файла. Для волокон используйте параметр dwStackReserveSizeэлемента CreateFiberEx. Зафиксированный размер указывается в параметре dwStackCommitSize .

Функция SetThreadStackGuarantee задает минимальный размер стека, связанного с вызывающим потоком или волокном, который будет доступен во время любых исключений переполнения стека.

Как узнать размер стека c

я так понимаю, что адрес переменной ch, указывает на нулевое смещение в стеке этого блока.
в общем, запустил. долго ждал, дождался 399534551
как-то многовато.
что не так?
проверял в линукс.

Сообщение отредактировано: niXman — 16.06.10, 11:27
Сообщ. #2 , 16.06.10, 12:13

Рейтинг (т): 150

niXman
Ну и чё такого? Он у тебя обнулил страницу «стека» и пошел портить память дальше. Нужно узнавать платформозависимыми функциями

Сообщ. #3 , 16.06.10, 12:32
Рейтинг (т): 241
Цитата niXman @ 16.06.10, 11:26
я так понимаю, что адрес переменной ch, указывает на нулевое смещение в стеке этого блока.

Нет.
В общем случае «main» — это процедура, которая вызывается из старт-апа.

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

Совсем не понятно, как ты предполагал узнать размер стека
выше приведённым алгоритмом ?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *