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

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

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

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

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

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

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

Поражается во втором конструкторе.

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

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

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

1 Ответ

2 голосов
/ 25 июня 2009

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

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

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

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

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

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

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

...