@asvishnyakov
Программист

Странная, зависящая от версии .NET Framework, проблема со сборкой мусора?

В моём проекте есть интересный баг с юнит-тестами, который проявляется только в .NET 4.5, но не в .NET 4.0. Здесь находится исходный код, а здесь — архив с бинарниками.

Шаги, чтобы воспроизвести проблему:
1. Скачайте исходный код и бинарники
2. Скопируйте папку Binary в папку Interop\Main\
3. Запустите unit тесты из сборки Interop.Core.Tests.NETFX45

Тест IsAliveAfterCollectionWork должен упасть. Если вы попробуете посмотреть память с помощью профайлера (я использую бесплатный dotMemory 4.0 EAP с настройками Profile .NET process -> Collection every N-th object: 1, Memory traffic: Collect и Use profiler API), то вы увидете, что массив MarkedObject[] не собирается сборщиком мусора, хотя на него нет никаких ссылок.

Моя конфигурация:
- Windows 8.1
- .NET Framework 4.5.1
- Я использую Visual Studio 2012, но 2010 и 2013 тоже установлены
  • Вопрос задан
  • 3278 просмотров
Пригласить эксперта
Ответы на вопрос 3
@mayorovp
А что тут странного? GC вам ничем не обязан, если объект перешел в следующее поколение - Collect его может проигнорировать.

Попробуйте GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, true);
Ответ написан
andreycha
@andreycha
В дебаг-режиме локальные переменные оставляются в живых до конца текущего скоупа. Это сделано для того, чтобы работали функции Locals, Auto, т.е. чтобы вы в любой момент при отладке могли посмотреть состояния локальных переменных. У меня скорее вопрос почему тест у вас не падает в 4.0.
Ответ написан
Собрал VS 13 из исходников.

Если запускать Resharper'овским test runner'ом - тест проходит
Если запускать Resharper'овским test runner'ом в debug - тест падает
Если запускать VS test runner'ом - тест падает

Если сделать консольное приложение - то остается 1 объект в WeakReferencesStorage

Возможно стоить копать в сторону работы GC в debug окружении
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы