Почему MemoryStream не утилизируется? - PullRequest
1 голос
/ 29 февраля 2020

Я пытаюсь провести простой тест с использованием dotMemory. Я ожидаю, что следующий тест пройдет успешно:

[Test]
public void MemoryStream_is_disposed()
{
    using (var stream = new MemoryStream()) { }
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    dotMemory.Check(memory => memory.GetObjects(where => where.Type.Is<MemoryStream>()).ObjectsCount.Should().Be(0));
}

Но это не так!

enter image description here

Почему и для чего Что мне нужно сделать, чтобы пройти тест?

Возможно, поэтому в моем коде есть утечки памяти.

1 Ответ

2 голосов
/ 01 марта 2020

Утилизированные и , имеющие право на сбор мусора означают две разные вещи. В частности, ваш stream имеет право на сборку мусора не потому, что он был удален, а потому, что у вас нет выдающихся ссылок на этот объект в точке, которую вы называете GC.Collect.

Но, как указывает @alexeilevenkov, отладочная версия G C не так агрессивна во время фазы Mark , поддерживая ссылки живыми, пока ссылка находится в области действия функции (позволяя Вы должны проверить ссылку на поток, пока не закончится функция). Право на сборку мусора означает, что объект может получить сборщик мусора. Однако, G C должен решить, когда вещи будут фактически собраны.

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

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

Почему вы думаете, что у вас есть память утечки в вашем коде? Трудно обнаружить истинные утечки памяти в управляемом коде

...