Как изменить размер стека по умолчанию для управляемого исполняемого файла.net

StackOverflow https://stackoverflow.com/questions/1042345

Вопрос

Мы обнаружили, что одна из наших автоматически сгенерированных сборок генерирует исключение StackOverflowException для метода new().Этот класс имеет (пожалуйста, потерпите) более 400 простых свойств, которые инициализируются (большинство по умолчанию (строка) и т. д.) в конструкторе.

Мы замечаем, что на 64-битной версии все в порядке, но на 32-битной — просто на ура!

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

Мы бы особенно.заинтересованы в решениях, включающих app.config, если это возможно.Но я реалист, поэтому все будет хорошо.

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

  • создает пустой экземпляр класса.
  • вызывает нестатический метод (Clone) класса, первой задачей которого является создание и пустой экземпляр, готовый передать свойства.

Он взрывается, когда попадает во второй конструктор.

Теперь, выполняя отладку исходного кода .net, мы видим, что переполнение стека находится в Guid.NewGuid(), который передается в качестве второго параметра конструктору.Фактическая строка кода — это вызов собственного вызова CoCreateGuid().

Поэтому, хотя это может быть ошибка в CoCreateGuid(), мы хотим исключить эту проблему из нашего кода.Моя первая мысль — значительно увеличить размер стека и посмотреть, повторится ли эта ошибка.Затем, поскольку я думаю, что мы можем контролировать все варианты использования, следует заменить конструктор инициализацией объекта — думаю, это может уменьшить нагрузку на стек.

Нб.Мы можем предотвратить возникновение ошибки, удалив из класса только свойство int.

Это было полезно?

Решение

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

Другой вариант (также упомянутый на этой странице) — создать новый поток с «правильным» размером стека.На странице упоминаются плюсы и минусы этого подхода.

Я был бы удивлен, если бы причиной проблемы была установка 400 свойств в конструкторе...это будет один большой кадр стека – но если у вас нет несколько большие кадры стека в стеке, я ожидал, что все будет в порядке.Другая возможность заключается в том, что где-то у вас бесконечная рекурсия :)

РЕДАКТИРОВАТЬ:Альтернативное предложение...

Вероятно, у вас в этом конструкторе много локальных переменных?(В противном случае он не должен занимать больше стека, чем любой другой вызов.) Можно ли разделить конструктор на несколько методов, установив, скажем, 20 полей для каждого метода?По общему признанию, это будет сложно, если поля доступны только для чтения.

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

Просто чтобы проверить, это является класс, а не структура, верно?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top