我正在调查一个.net 1.1 Web应用程序的问题,似乎我们有很多“内部连接致命错误”异常可能是连接对象保持打开或未正确处理。 Web服务器最终在重负载下崩溃。我检查了代码,我们实际上是在try catch finally的所有地方调用sqlconnection.close()
该项目实现以下模式。有人能告诉我它是否会导致内存泄漏?
aspx网页在Private Sub Page_Load
中进行以下调用Dim oDictionary As New dbDictionary
tagVal = oDictionary.GetTag(41)
其中dbDictionary用于从DB获取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中的GC效率不高)
此外,我想知道我可以使用perfmon在Web服务器上监视什么来指示内存泄漏。我正在计划修改此代码,并希望指出问题已得到解决。我在SqlClient中看到了一个趋势:当前#连接池 - 它每天稳定增长1000(这是与该进程关联的当前池数)。所以我想知道它是否应该随着Sessions减少而下降。我正在查看(\ ASP.NET Apps v1.1.4322( Total )\ Sessions Active)以查看服务器负载的样子。
答案 0 :(得分:0)
此代码:
'new sqlconnection object for another sqlcommand
Dim dictConnection As New SqlConnection
dictConnection = _connection 'At this point the _connection is closed.
创建两个SqlConnection
(As New SqlConnection
正在创建一个),第一个永远不会被处置。这当然可能是泄漏连接的来源。
您还处置了您从未创建的连接_connection
(无法查看创建的位置)。假设它是以1:1创建的,这不应该是一个大问题,但如果在Try
块之前发生异常,则此连接也不会被处理掉。如果没有为此代码1:1创建_connection
,那么如果其他人尝试使用此代码,您最终可能会获得ObjectDisposedException
。