Я исследую проблему с веб-приложением .net 1.1, когда кажется, что у нас было довольно много исключений «Неустранимая ошибка внутреннего соединения», возможно, объекты соединения остаются открытыми или не удаляются должным образом. В конечном итоге веб-сервер падает при большой нагрузке. Я проверил код, и мы на самом деле вызываем sqlconnection.close () во всех местах в try catch, наконец
В проекте реализован следующий шаблон. Может кто-нибудь сказать мне, если это выглядит, как это может вызвать утечку памяти?
Веб-страница aspx выполняет следующий вызов в Private Sub Page_Load
Dim oDictionary As New dbDictionary
tagVal = oDictionary.GetTag(41)
где dbDictionary используется для получения таблицы sql из БД
Public Class dbDictionary
Inherits DBInteractionBase
Public Function GetTag(ByVal tagId)
'uses the _connection connection object and Executes sql which sometimes throws a sql exception, but closes the connection in finally
GetDictConnectionString()
'new sqlconnection object for another sqlcommand
Dim dictConnection As New SqlConnection
dictConnection = _connection 'At this point the _connection is closed.
'I think the dictConnection is a reference to _connection
Dim cmdToExecute As SqlCommand = New SqlCommand
' // Use base class' connection object
cmdToExecute.Connection = dictConnection
Try
' // Open connection.
dictConnection.Open()
' // Execute query.
adapter.Fill(toReturn)
Catch ex As Exception
Throw New Exception("Error occured.", ex)
Finally
' // Close connection.
dictConnection.Close()
cmdToExecute.Dispose()
adapter.Dispose()
End Try
End Function
Private Function GetDictConnectionString()
' initialize SqlCommand... Use base class _connection object
cmdToExecute.Connection = _connection
Try
_connection.Open()
adapter.Fill(toReturn)
Catch ex As Exception
Return "Error" ' Could this be the issue? The original exception isn't released?
Finally
_connection.Close()
cmdToExecute.Dispose()
adapter.Dispose()
End Try
End Class
Вот DBInteractionBase, который он наследует
Public MustInherit Class DBInteractionBase
Inherits System.Web.UI.Page
Protected _connection As SqlConnection
Public Sub New()
_connection = New SqlConnection
_connection.ConnectionString = "some conn string"
End Sub
Public Overloads Sub Dispose()
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
Protected Overridable Overloads Sub Dispose(ByVal isDisposing As Boolean)
' // Check to see if Dispose has already been called.
If Not _isDisposed Then
If isDisposing Then
' // Dispose managed resources.
_connection.Dispose()
_connection = Nothing
End If
End If
_isDisposed = True
End Sub
Теперь, когда код выполняется, Dispose никогда не вызывается вызывающей веб-страницей. Что мне интересно, так это когда код утилизации выполняется GC? Возможно, я вижу еще одну проблему: если GetDictConnectionString имеет исключение, оно никогда не сбрасывает исходное исключение sql. Это как-то оставит объект sql в памяти? Имейте в виду, что это приложение .NET 1.1 и (сборщик мусора в .NET 1 не очень эффективен)
Также мне интересно, что я могу контролировать на веб-сервере, используя perfmon, чтобы показать утечку памяти. Я планирую изменить этот код и хотел бы индикатор, что проблема была решена. Я вижу тенденцию в SqlClient: Текущие пулы # соединений - они постоянно растут на 1000 каждый день (это текущее количество пулов, связанных с процессом.), Поэтому мне интересно, должно ли оно уменьшиться с уменьшением количества сеансов. Я смотрю (\ ASP.NET Apps v1.1.4322 ( Total ) \ Sessions Active), чтобы увидеть, как выглядит загрузка сервера.