Почему одновременный сборщик мусора иногда вызывает исключение ExecutionEngineException (для MSDN)?

Согласно MSDN, есть "совет" о том, что приложение.NET работает под большой нагрузкой с одновременной сборкой мусора (либо <gcConcurrent enabled="true"/> или не указано, так как это поведение по умолчанию) может вызвать исключение ExecutionEngineException. Кто-нибудь знает статью Microsoft KB или другой источник, который предоставляет дополнительную информацию об этом?

Мы испытали это непосредственно с приложением-службой Windows на базе NHibernate 3.2, которое неизбежно зависнет после нескольких часов работы. Мы смогли отследить исключение для вызова ISession.Flush().

На nhusers есть ветка, сообщающая о том, что кажется, что та же самая проблема. Его предложенный обходной путь, который должен был отключить одновременный сборщик мусора, до сих пор работал для нас, хотя переход на серверный режим сборщика мусора (<gcServer enable="true"/>), которая неявно отключает одновременный сборщик мусора, также сделала свое дело.

Прежде чем отправлять это в MS как ошибку, я хотел бы узнать, есть ли у кого-нибудь дополнительная информация о сопутствующей нестабильности GC, о которой упоминается в подсказке.

1 ответ

Решение

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

Как отметил @casperOne в своем комментарии, это исключение помечено как устаревшее в.NET 4.0, хотя это не обязательно означает, что сборщик мусора все еще не может войти в то же состояние, из-за которого он вызывает исключение в.NET 3.5. Если GC действительно оказался в том же состоянии, среда выполнения выдаст команду FailFast и завершит работу, а не вызовет исключение.

Другие вопросы по тегам