0

.net 1.1 웹 응용 프로그램에서 연결 개체가 열려 있거나 제대로 처리되지 않았을 때 "내부 연결 치명적인 오류"예외가있는 것으로 보이는 문제를 조사하고 있습니다. 웹 서버는로드가 많은 경우 결국 충돌합니다. 코드를 확인한 후 try catch의 모든 위치에서 실제로 sqlconnection.close()를 호출합니다.메모리 누출/잘못 작성된 코드 또는 둘 다 - sqlconnection을 올바르게 처리 하시겠습니까?

프로젝트는 다음 패턴을 구현합니다. 누군가가 이것이 메모리 누수의 원인이 될 수 있다고 생각되면 저에게 말해 줄 수 있습니까?

영문 웹 페이지는 개인 서브에 다음 호출이

여기
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입니다 dbDictionary는 DB에서 SQL 테이블을 얻기 위해 사용된다

Dim oDictionary As New dbDictionary 
tagVal = oDictionary.GetTag(41) 

을하여 Page_Load하게

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 never call gets gets 호출 웹 페이지에 의해 편집 됨. 처분 코드가 GC에 의해 실행되면 궁금한 점은 무엇입니까? 내가 볼 수있는 또 다른 문제는 GetDictConnectionString에 예외가있는 경우 원래 SQL 예외를 다시 발생시키지 않는다는 것입니다. 어떻게 든 SQL 객체를 메모리에 남겨 두겠습니까? 이것은 .NET 1.1 응용 프로그램이고 (.NET 1의 GC는 매우 효율적이지 않습니다.)

또한 perfmon을 사용하여 웹 서버에서 메모리 누수를 모니터링 할 수 있는지 궁금합니다. 나는이 코드를 수정할 계획이며 문제가 해결되었다는 표시를 원합니다. SqlClient : Current # 연결 풀의 트렌드를 볼 수 있습니다. 세션 수가 줄어들면 계속 낮추어야하는지 궁금해지기 때문에 매일 1000 번씩 꾸준히 증가하고 있습니다. 나는 (\ ASP.NET Apps v1.1.4322 (합계) \ Sessions Active)에서 서버 부하가 어떻게되는지를보고있다.

+0

dictConnection을 새로운 SqlConnction으로 선언 한 다음이를 기존 _connection에 다시 지정하는 이유는 무엇입니까? 나는 또한 당신이 정말로 SqlConnections를 처분하고 싶지 않다는 것을 지적해야한다. Close를 실행하면 연결 풀로 반환됩니다. 동일한 연결 문자열을 계속 사용하면 자동으로 다시 사용됩니다. – tomasmcguinness

+0

왜 내가 새 sqlconnection 객체를 선언했는지 모르겠지만 리팩토링하는 사람은 내 목록에 있습니다. 나는 그것이 우리가 가지고있는 문제들에 어떤 함의가 있는지를 알고 싶다. SqlConnection 개체를 올바르게 처리하지 않으면 메모리에 남아있을 가능성이 있습니까? – kiev

+0

SqlConnections는 기본적으로 유지되지만 성능면에서 일반적으로 좋은 점이 있으며 풀링 된 개체 수가 설정된 크기로만 증가해야합니다. – tomasmcguinness

답변

0

이 코드 :

'new sqlconnection object for another sqlcommand 
Dim dictConnection As New SqlConnection 
dictConnection = _connection 'At this point the _connection is closed. 

합니다 (As New SqlConnection 하나 만드는)이 SqlConnection의를 생성하고, 첫 번째 배치되지 않을 것입니다. 이것은 분명히 새는 연결의 원천이 될 수 있습니다.

작성한 적이없는 _connection 연결도 삭제됩니다 (생성되는 곳을 볼 수 없음). 1 : 1로 생성되었다고 가정하면 큰 문제는 아니지만, Try 블록 전에 예외가 발생하면이 연결도 처리되지 않습니다. _connection이이 코드에 대해 1 : 1로 생성되지 않으면 다른 것이 사용하려고하면 ObjectDisposedException이 될 수 있습니다.

관련 문제