Это утечка памяти? Пожалуйста, проверьте код ниже

#.net #vb.net #memory-leaks

#.net #vb.net #утечки памяти

Вопрос:

В моем приложении VB я использую наборы данных следующим образом:

 Dim rs As DataSet
Dim sql As String = "some sql"
rs = GetDataSet(sql, db)
' Work with the data

sql = "another sql"
rs = GetDataSet(sql, db)
' More code

rs.Dispose
 

Приведет ли это к утечке памяти, если я добавлю dispose в конце подраздела или я должен утилизировать rs после каждого его использования?

Комментарии:

1. Нет, это не утечка. Сборщик мусора позаботится об очистке неиспользуемых объектов.

2. @NicoSchertler Пожалуйста, не используйте слова «сборщик мусора» и «удаление» в одном и том же предложении, это разные вещи. Сборщик мусора никогда ничего не удаляет. Он только собирает. Это может привести к вызову финализатора объекта, и этот финализатор может в конечном итоге вызвать Dispose, но это все равно не входит в обязанности сборщиков мусора. В SO достаточно путаницы в отношении обязанностей сборщика мусора и одноразовых объектов, давайте не будем вносить еще больший вклад в эту путаницу.

3. Скорее всего, это не утечка. Если GetDataSet , о котором мы ничего не знаем, где-то хранит ссылку на возвращенный набор данных, это может быть утечка, но если он просто создает новый объект и возвращает его, то нет, это не будет утечкой.

Ответ №1:

Ну, проблема с «утечками памяти» заключается в том, что в .NET они не такие, как в языках с прямым управлением памятью (например, C / C ). В .NET утечка памяти почти всегда является результатом ссылки на объект из одного из корней сборщика мусора, вызванной плохо управляемыми зависимостями между объектом на графике, а не отсутствием освобождения памяти.

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

Хотя у меня есть несколько хороших примеров.ЧИСТАЯ утечка памяти в моей статье, http://alexatnet.com/articles/memory-leaks-in-net-applications , в нем отсутствует один тривиальный пример — отсутствует Dispose в случае, когда данные объекта состоят из двух частей — крошечная управляемая оболочка вокруг огромного массива неуправляемых данных (другими словами, что-то вроде изображений). Представьте, что приложение создает несколько изображений и не удаляет их, когда они больше не требуются. В этом случае GC не будет собирать мусор и уничтожать изображения, поскольку порог GC не будет достигнут, а изображения быстро потребляют всю доступную виртуальную память и завершают работу приложения.

Рассмотрим противоположное — довольно большое.СЕТЕВОЙ объект и крошечный неуправляемый ресурс, такой как небольшой COM-объект. В этом случае, даже если Disposed не вызывается явно, интенсивное использование этих объектов будет вызывать GC достаточно часто, чтобы очистить все объекты, которые не удаляются вручную, и у вас никогда не будет исключения OutOfMemory.

Вот почему трудно определить, содержит ли ваш пример кода «утечку памяти» или, если быть более точным, вызовет ли это проблемы?

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

Поэтому, если вы хотите быть уверенным, перепишите его с помощью «using» http://msdn.microsoft.com/en-GB/library/htd05whh.aspx . Если вам нравится exreme и вы считаете, что ваша жизнь слишком проста, если вы не работаете допоздна, отлаживая проблемы OutOfMemory — просто оставьте все как есть.

Извините за длинный ответ на такой простой вопрос.