Ich untersuche ein Problem mit einer. NET 1.1 Webanwendung, wo es scheint, dass wir ziemlich viele "Internal connection fatal error" Ausnahmen möglicherweise die Verbindungsobjekte offen oder nicht ordnungsgemäß entsorgt haben. Der Webserver stürzt schließlich unter hoher Last ab. Ich überprüfte den Code und wir rufen in der Tat sqlconnection.close() an allen Stellen in der Try Catch schließlichSpeicherleck/schlecht geschriebenen Code oder beides - ordnungsgemäße Entsorgung von sqlconnection?
Das Projekt implementiert das folgende Muster. Kann mir jemand sagen, ob es so aussieht, als könnte dies zu einem Speicherleck führen?
Die aspx Webseite macht den folgenden Aufruf in Private Sub Page_Load
Dim oDictionary As New dbDictionary
tagVal = oDictionary.GetTag(41)
wo dbDictionary für das Erhalten einer SQL-Tabelle von DB verwendet wird
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
Hier ist die DBInteractionBase, dass es erbt
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
Jetzt, wenn der Code ausgeführt wird, ruft Dispose nie einen Anruf ab Ed von der aufrufenden Webseite. Was ich mich wundere ist, wenn der Verfügungscode überhaupt vom GC ausgeführt wird? Ein anderes Problem, das ich möglicherweise sehe, ist, dass, wenn GetDictConnectionString eine Ausnahme hat, es niemals die ursprüngliche sql-Ausnahme wiederholt. Würde das das sql-Objekt irgendwie im Speicher belassen? Denken Sie daran, diese eine Anwendung .NET 1.1 ist und (GC in .NET 1 ist nicht sehr effizient)
Auch ich frage mich, was ich auf dem Web-Server mit Perfmon überwachen kann einen Speicherverlust anzuzeigen. Ich plane, diesen Code zu ändern und möchte einen Indikator, dass das Problem behoben wurde. Ich sehe einen Trend in SqlClient: Aktuelle # Verbindungspools - es wächst stetig 1000 jeden Tag (Es ist die aktuelle Anzahl der Pools mit dem Prozess verbunden.) Ich frage mich also, ob es gehen sollte, wie die Sitzungen sinken. Ich schaue (\ ASP.NET Apps v1.1.4322 (Gesamt) \ Sitzungen aktiv), um zu sehen, wie die Serverlast aussieht.
Warum deklarieren Sie dictConnection als eine neue SqlConnction und dann auf die bestehende _connection? Ich sollte auch darauf hinweisen, dass Sie SqlConnections nicht wirklich loswerden wollen. Wenn Sie Schließen ausführen, werden sie an den Verbindungspool zurückgegeben. Sobald Sie die gleiche Verbindungszeichenfolge verwenden, werden sie automatisch wiederverwendet. – tomasmcguinness
Ich weiß nicht, warum sie ein neues sqlconnection-Objekt deklarieren, aber das ist auf meiner Liste zu refactor. Ich möchte nur wissen, ob das Auswirkungen auf die Probleme hat, die wir haben. Wenn Sie das SqlConnection-Objekt nicht ordnungsgemäß entsorgen, hat es die Möglichkeit, im Speicher zu verweilen? – kiev
SqlConnections wird standardmäßig beibehalten, aber für die Leistung ist das im Allgemeinen eine gute Sache, und es sollte nur die Anzahl der gepoolten Objekte auf eine festgelegte Größe erhöhen. – tomasmcguinness