Распределение стекового пространства по умолчанию, указанное $M
, является глобальным для всех потоков в процессе, которые не определяют свои собственные специфические требования.Для этого достаточно 60M, гораздо больше, чем когда-либо будет расти любой стек.
Диалоги файлов по сути являются размещенной версией Windows Explorer.Они загружают расширения оболочки в ваш процесс для таких вещей, как миниатюры, обработчики столбцов, контекстные меню и т. Д. Поскольку Windows становится все более функциональной, и MS, и третьи стороны могут свободно использовать все больше ресурсов - включая потоки - для асинхронного добавления дополнительной информации,без блокировки интерфейса.Простой тест с notepad.exe
на моей 64-битной машине с Windows 7 показывает, что у него 1 поток перед диалогом, но 19 потоков, пока диалог открыт.В 32-разрядном процессе с резервированием стека по умолчанию, близким к 60M, требуется резервировать более 1 ГБ или более половины общего адресного пространства, доступного для 32-разрядных приложений по умолчанию.Если в приложении вообще обрабатывается много данных, очень легко увидеть, что из-за фрагментации памяти не хватает адресного пространства - весь код из EXE, системных библиотек DLL и т. Д. Тоже должен где-то помещаться.60M - это просто слишком большое резервирование стека по умолчанию, чтобы ожидать, что оно будет работать без проблем.
Рассматривали ли вы перенос своих глубоко рекурсивных вычислений в создаваемый вами поток?Вам нужно было бы напрямую использовать BeginThread()
из System
, чтобы явно указать резервирование стека.
В качестве альтернативы, можно ли попытаться уменьшить использование стека вашими алгоритмами?Если вы размещаете записи или массивы в стеке, рассмотрите возможность их динамического распределения.Если у вас есть функция, которая многократно повторяется (вложена глубоко) и имеет много локальных переменных, рассмотрите возможность создания записи, содержащей локальные переменные, и ее динамического распределения.Если вы зависите от рекурсии для последовательной работы (например, обход деревьев / графов в глубину), рассмотрите возможность использования рекурсии просто для последовательной работы (например, добавьте узлы в список) и выполняйте реальную обработку итеративно.И при необходимости посмотрите на переделку алгоритма для работы с явным стеком.Другое преимущество наличия явного стека состоит в том, что при желании вы можете тривиально переключаться на ширину, используя очередь вместо стека, однострочную, если реализации стека и очереди используют полиморфный интерфейс.