#vb.net #memory-leaks #odbc
#vb.net #утечки памяти #odbc
Вопрос:
Я создал DLL-оболочку для базы данных, которая предоставляет мне объектный уровень API для моей базы данных. У меня возникают проблемы из-за того, что сборщик мусора в VB.net похоже, что при уничтожении объектов беспорядок не устраняется. Я относительно уверен, что сделал все, чтобы очистить объект, включая реализацию интерфейса IDispose для каждого объекта, чтобы уничтожить все.
Когда я создаю экземпляр объекта, я выполняю чтение из базы данных и заполняю объект на основе соответствующей записи в базе данных, ситуация становится ужасной. Это работает хорошо, однако, когда я повторяю создание и уничтожение 1000-х и 1000-х этих объектов, объем памяти просто продолжает увеличиваться.
Затем мне пришло в голову: может быть, мои объекты не будут очищаться из-за того, что я использую общую ссылку на базу данных ODBC внутри своих объектов? сохранит ли это мои объекты живыми, несмотря на все мои усилия?
Например: (примечание: clsSharedConfig.g_objDatabaseConn является общим экземпляром OdbcConnection)
Dim cmd As New OdbcCommand("SELECT * FROM FILES WHERE CID = " amp; p_lngID, clsSharedConfig.g_objDatabaseConn)
Dim data As OdbcDataReader
Try
cmd.CommandType = CommandType.Text
data = cmd.ExecuteReader()
Кто-нибудь может предложить какую-либо другую причину, по которой у меня это происходит? Я не хочу прибегать к использованию GC.Собирайте статменты везде, чтобы держать это под контролем!
Спасибо,
Эндрю
Комментарии:
1. Общий доступ к соединению в порядке, если ваш код обрабатывает его должным образом после завершения. Когда вы говорите, что объем памяти увеличивается, о каких объектах сообщается в профилировщике памяти.
2. Вы уверены, что утилизируете свои устройства чтения данных, когда закончите с ними? Вы должны создавать их экземпляры в блоке Using.
Ответ №1:
Вы должны закрыть программу чтения, чтобы освободить ресурсы. Смотрите ниже
Private Sub CmdReaderSample(ByVal cn As OleDbConnection, ByVal strCmd As String)
Dim cmd As OleDbCommand = New OleDbCommand(strCmd, cn)
cmd.CommandType = CommandType.Text
Dim objReader As OleDbDataReader = cmd.ExecuteReader
Try
'read some stuff objReader.Read()
Finally
objReader.Close()
End Try
End Sub
Также проверьте, когда ваши объекты загружаются из Reader, возможно, вы также сохраняете ссылку там.
Утечки памяти лучше устраняются с помощью профилировщика памяти, такого как Ants memory profiler
Комментарии:
1. Блок использования был бы немного чище.
Ответ №2:
Вы пробовали каждый раз просто создавать экземпляр нового объекта connection? платформа .net Framework будет обрабатывать фактический пул соединений под капотом, поэтому я не уверен, что попытка поделиться этим объектом в любом случае вам сильно поможет.
Ответ №3:
Итак, я попробовал ваши предложения (кстати, спасибо!), Но, увы, без изменений…
Затем, просто для справки, я покопался в настройках приложения для моей DLL. Я заметил, что по какой-то глупой / неизвестной причине у меня была включена совместимость с COM.
Итак, я снял этот флажок, исходя из того, что мне не НУЖНА совместимость с COM, и это просто замутняло ситуацию в поиске решения. Как только я это сделал и повторно запустил его, утечка памяти исчезла!
Серьезно? это было ВСЕ? Мне нужно, чтобы кто-нибудь медленно объяснил мне это, возможно, используя ручных марионеток.
Профилировщик памяти подтвердил, что моя утечка была в неуправляемой памяти.
вот уже 2 дня, как я не возвращаюсь…
Эндрю