Я использую COM-объект из .NET с помощью взаимодействия. Объект в основном получает данные из сокета и запускает некоторые события для обработки уровня .NET. Однако, через некоторое время COM-объект перестает запускать события, которые, как выяснилось позже, были вызваны сбором мусора.
Структура исходного кода аналогична приведенной ниже:
static void Main(string[] args)
{
MyEventGen gen = new MyEventGen();
WeakReference wr = new WeakReference(gen);
gen.ReceiveDataArray +=
new _IMyEventGenEvents_ReceiveDataArrayEventHandler(gen_ReceiveDataArray);
while (true)
{
Thread.Sleep(1000);
Console.WriteLine(wr.IsAlive);
}
}
static void gen_ReceiveDataArray(ref Array indices, ref Array values)
{
// do nothing
}
Что я знаю на данный момент:
Из чего Я понимаю, что объект gen
ни в коем случае не подлежит сборке мусора. Поскольку объект все еще активен в области Main
. Но пока что результат показывает, что объект был собран сборщиком мусора.
Объект собирает мусор только при сборке как Release и запуске без отладки . Выполнение сборок отладки / запуск обоих режимов под отладчиком - это нормально.
Программа напечатает первое «False» точно после первой коллекции Gen # 0 .
Получив доступ к объекту в а цикл
, например Console.WriteLine (gen.ToString ())
, предотвратить сборку мусора!
Добавив еще одно статическое поле класса Program
, чтобы сохранить ссылку на него, он также не сможет GC'd.
Пытаясь с другой загрузкой данных, я обнаружил, что GC собирает объект только тогда, когда частные байты превышают пороговое значение в ~ 3X МБ.
Проверка с помощью CLRProfiler , упомянутый объект был GC'd, как и предполагалось.
Пропустил ли я некоторые важные концепции .NET GC? Можно ли узнать причину GC'd объекта? Это, возможно, известная ошибка GC?
Я использую VS 2008 + .NET 3.5 SP1. Цени свои мысли. Спасибо!