Memory Leaking in VB.NET

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Brano

    #1

    Memory Leaking in VB.NET

    Hi all,

    I have a VB.NET Dll that is invoked via BizTalk 2002 AIC over Http
    protocol.

    the Dll is making a connection using a 3rd party connector to a Unidata
    database (old legacy stuff) All I am doing is creating an instance of
    the class and then using its two methods (Connect CloseConnection )

    and then setting the instance to Nothing.

    However I am experiencing a big memory leak when I run stress test on
    my DLL (the DLLHOST.EXE for the particular DLL goes up and up until it
    crashes the server)

    I have researched Garbage collector and used it but it doesnt help...

    Here Is my code

    Dim moudconn As New CUniData
    moudconn.Connec t(strResult)

    moudconn.CloseC onnection()

    moudconn = Nothing

    GC.Collect()
    Dispose()

    Can anybode see anything I am doing wrong??

  • NickP

    #2
    Re: Memory Leaking in VB.NET

    Hi Brano,

    Does your moudconn object have a dispose method?

    If so call that before setting it to Nothing,

    moudconn.Dispos e()
    moudconn = Nothing

    ... Hope this helps.

    Nick.

    "Brano" <bpajer@gmail.c om> wrote in message
    news:1140528619 .206983.283980@ g14g2000cwa.goo glegroups.com.. .[color=blue]
    > Hi all,
    >
    > I have a VB.NET Dll that is invoked via BizTalk 2002 AIC over Http
    > protocol.
    >
    > the Dll is making a connection using a 3rd party connector to a Unidata
    > database (old legacy stuff) All I am doing is creating an instance of
    > the class and then using its two methods (Connect CloseConnection )
    >
    > and then setting the instance to Nothing.
    >
    > However I am experiencing a big memory leak when I run stress test on
    > my DLL (the DLLHOST.EXE for the particular DLL goes up and up until it
    > crashes the server)
    >
    > I have researched Garbage collector and used it but it doesnt help...
    >
    > Here Is my code
    >
    > Dim moudconn As New CUniData
    > moudconn.Connec t(strResult)
    >
    > moudconn.CloseC onnection()
    >
    > moudconn = Nothing
    >
    > GC.Collect()
    > Dispose()
    >
    > Can anybode see anything I am doing wrong??
    >[/color]


    Comment

    • Brano

      #3
      Re: Memory Leaking in VB.NET

      Hi, It doesnt actually...

      But I can access this class and reprogram it.

      I have tried to add the microsoft code to do that which is:

      Public MustInherit Class CUniDataBase
      Implements IDisposable

      ' NB - ALWAYS CLOSE CONNECTION ON EXIT

      ' Pointer to an external unmanaged resource.
      Private handle As IntPtr
      ' Other managed resource this class uses.
      Private component As Component
      ' Track whether Dispose has been called.
      Private disposed As Boolean = False

      ' The class constructor.
      Public Sub New(ByVal handle As IntPtr)
      Me.handle = handle
      End Sub

      ' Implement IDisposable.
      ' Do not make this method virtual.
      ' A derived class should not be able to override this method.
      Public Overloads Sub Dispose() Implements IDisposable.Dis pose
      Dispose(True)
      ' This object will be cleaned up by the Dispose method.
      ' Therefore, you should call GC.SupressFinal ize to
      ' take this object off the finalization queue
      ' and prevent finalization code for this object
      ' from executing a second time.
      GC.SuppressFina lize(Me)
      End Sub

      ' Dispose(bool disposing) executes in two distinct scenarios.
      ' If disposing equals true, the method has been called directly
      ' or indirectly by a user's code. Managed and unmanaged
      resources
      ' can be disposed.
      ' If disposing equals false, the method has been called by the
      ' runtime from inside the finalizer and you should not
      reference
      ' other objects. Only unmanaged resources can be disposed.
      Private Overloads Sub Dispose(ByVal disposing As Boolean)
      ' Check to see if Dispose has already been called.
      If Not Me.disposed Then
      ' If disposing equals true, dispose all managed
      ' and unmanaged resources.
      If disposing Then
      ' Dispose managed resources.
      component.Dispo se()
      End If

      ' Call the appropriate methods to clean up
      ' unmanaged resources here.
      ' If disposing is false,
      ' only the following code is executed.
      CloseHandle(han dle)
      handle = IntPtr.Zero
      End If
      disposed = True
      End Sub

      ' Use interop to call the method necessary
      ' to clean up the unmanaged resource.
      <System.Runtime .InteropService s.DllImport("Ke rnel32")> _
      Private Shared Function CloseHandle(ByV al handle As IntPtr) As
      [Boolean]
      End Function

      ' This finalizer will run only if the Dispose method
      ' does not get called.
      ' It gives your base class the opportunity to finalize.
      ' Do not provide finalize methods in types derived from this
      class.
      Protected Overrides Sub Finalize()
      ' Do not re-create Dispose clean-up code here.
      ' Calling Dispose(false) is optimal in terms of
      ' readability and maintainability .
      Dispose(False)
      MyBase.Finalize ()
      End Sub


      But if I cann the dispose now I get Object reference not set to an
      instance of an object error...

      ;o(

      Comment

      • AMDRIT

        #4
        Re: Memory Leaking in VB.NET

        Brano,

        Review this snippet and see if you can make use of the concepts within.

        Public MustInherit Class CUniDataBase
        Implements IDisposable

        Private disposedValue As Boolean = False ' To detect redundant calls
        Private myLegacy As Object ' Pointer to legacy database
        Private myConnection As String ' Holds connection information
        Private isInitialized As Boolean ' State flag of the unmanaged
        object

        Public Sub New(ByVal ConnectionStrin g As String)

        myConnection = ConnectionStrin g

        'myLegacy is not init'ed yet
        isInitialized = False

        End Sub

        Public Sub Connect()

        If Not isInitialized Then
        myLegacy = CreateObject("S omeContainer.So meObject")
        myLegacy.Connec tion = myConnection
        myLegacy.Connec t()
        isInitialized = True
        End If

        End Sub

        Public Sub Disconnect()

        If isInitialized AndAlso Not myLegacy Is Nothing Then
        'Free up pointers
        myLegacy.Discon nect()
        End If

        myLegacy = Nothing
        isInitialized = False

        End Sub

        #Region " IDisposable Support "

        ' This code added by Visual Basic to correctly implement the disposable
        pattern.
        Public Sub Dispose() Implements IDisposable.Dis pose
        ' Do not change this code. Put cleanup code in Dispose(ByVal disposing
        As Boolean) above.
        Dispose(True)
        GC.SuppressFina lize(Me)
        End Sub

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposedValu e Then
        If disposing Then
        ' TODO: free unmanaged resources when explicitly called
        Me.Disconnect()
        End If
        ' TODO: free shared unmanaged resources
        End If
        Me.disposedValu e = True
        End Sub

        Protected Overrides Sub Finalize()
        Dispose(False)
        MyBase.Finalize ()
        End Sub

        #End Region

        End Class


        "Brano" <bpajer@gmail.c om> wrote in message
        news:1140531143 .277168.32990@f 14g2000cwb.goog legroups.com...[color=blue]
        > Hi, It doesnt actually...
        >
        > But I can access this class and reprogram it.
        >
        > I have tried to add the microsoft code to do that which is:
        >
        > Public MustInherit Class CUniDataBase
        > Implements IDisposable
        >
        > ' NB - ALWAYS CLOSE CONNECTION ON EXIT
        >
        > ' Pointer to an external unmanaged resource.
        > Private handle As IntPtr
        > ' Other managed resource this class uses.
        > Private component As Component
        > ' Track whether Dispose has been called.
        > Private disposed As Boolean = False
        >
        > ' The class constructor.
        > Public Sub New(ByVal handle As IntPtr)
        > Me.handle = handle
        > End Sub
        >
        > ' Implement IDisposable.
        > ' Do not make this method virtual.
        > ' A derived class should not be able to override this method.
        > Public Overloads Sub Dispose() Implements IDisposable.Dis pose
        > Dispose(True)
        > ' This object will be cleaned up by the Dispose method.
        > ' Therefore, you should call GC.SupressFinal ize to
        > ' take this object off the finalization queue
        > ' and prevent finalization code for this object
        > ' from executing a second time.
        > GC.SuppressFina lize(Me)
        > End Sub
        >
        > ' Dispose(bool disposing) executes in two distinct scenarios.
        > ' If disposing equals true, the method has been called directly
        > ' or indirectly by a user's code. Managed and unmanaged
        > resources
        > ' can be disposed.
        > ' If disposing equals false, the method has been called by the
        > ' runtime from inside the finalizer and you should not
        > reference
        > ' other objects. Only unmanaged resources can be disposed.
        > Private Overloads Sub Dispose(ByVal disposing As Boolean)
        > ' Check to see if Dispose has already been called.
        > If Not Me.disposed Then
        > ' If disposing equals true, dispose all managed
        > ' and unmanaged resources.
        > If disposing Then
        > ' Dispose managed resources.
        > component.Dispo se()
        > End If
        >
        > ' Call the appropriate methods to clean up
        > ' unmanaged resources here.
        > ' If disposing is false,
        > ' only the following code is executed.
        > CloseHandle(han dle)
        > handle = IntPtr.Zero
        > End If
        > disposed = True
        > End Sub
        >
        > ' Use interop to call the method necessary
        > ' to clean up the unmanaged resource.
        > <System.Runtime .InteropService s.DllImport("Ke rnel32")> _
        > Private Shared Function CloseHandle(ByV al handle As IntPtr) As
        > [Boolean]
        > End Function
        >
        > ' This finalizer will run only if the Dispose method
        > ' does not get called.
        > ' It gives your base class the opportunity to finalize.
        > ' Do not provide finalize methods in types derived from this
        > class.
        > Protected Overrides Sub Finalize()
        > ' Do not re-create Dispose clean-up code here.
        > ' Calling Dispose(false) is optimal in terms of
        > ' readability and maintainability .
        > Dispose(False)
        > MyBase.Finalize ()
        > End Sub
        >
        >
        > But if I cann the dispose now I get Object reference not set to an
        > instance of an object error...
        >
        > ;o(
        >[/color]


        Comment

        • Brano

          #5
          Re: Memory Leaking in VB.NET

          HI I think i have found the problem it is not my class because I have
          rewritten the code from it to the main program and executed it and it
          is creating the memory leek too.

          The problem is I have a 3rd party class that doesnt have a dispose
          method. It has however a OpenConnection method and a CloseConnection
          method but I call both of these and the memory leak is still there. I
          even set the object to Nothing afterwards but still the memory leek
          appears. Here is snippet of my code :


          Dim mobjUDConn As connection '# this object is declared in 3rd party
          DLL that is referenced
          Dim mobjUDDB As connDatabase '# this object is declared in 3rd
          party DLL that is referenced

          Const mcMultiDelim As String = "ý"
          Const mcColumnDelim As String = "þ"

          '# XXX means REMOVED FOR SECURITY PURPOUSES
          Dim sHost As String = "XXX.x.XXX. xx"
          Dim sPort As Int32 = XXXX
          Dim sUser As String = String.Empty = "admin"
          Dim sPassword As String = String.Empty = "XXXXXXX"
          Dim sDatabase As String = String.Empty = "XXX-XXXXXXXX"

          '#SUB CONNECT
          Dim ErrMsg As String
          Try
          If mobjUDConn Is Nothing Then
          mobjUDConn = New connection
          End If
          If mobjUDConn.isCo nnected = False Then
          With mobjUDConn
          .Host = sHost
          .Port = sPort
          .User = sUser
          .Password = sPassword
          .Database = sDatabase
          mobjUDConn.open ()
          End With
          End If
          If mobjUDDB Is Nothing Then
          mobjUDDB = New connDatabase
          End If
          If mobjUDDB.isConn ected = False Then
          mobjUDDB = mobjUDConn.getD atabase
          End If
          ErrMsg = ""
          Catch ex As Exception
          ErrMsg = ex.Message
          End Try

          '# Thats it connection opened
          '# Do reads / writes here

          '##### Close Connection ####
          mobjUDDB.close( )
          '# ##### PROBLEM HERE #######
          '# Problem is here mobjUDDB doesnt have a dispose method
          mobjUDConn.clos e()
          mobjUDConn.Disp ose()

          mobjUDDB = Nothing
          mobjUDConn = Nothing

          Comment

          • Jim Wooley

            #6
            Re: Memory Leaking in VB.NET

            You might want to consider wrapping the 3rd party class that is leaking with
            the USING functionality (in 2005). Another option to try is possibly wrap
            the call and set up a second app domain which can be sandboxed. You then
            create and destroy the app domain, thereby isolating the leak and disposing
            of it. Granted there is a performance penalty with the second app domain
            and the second domain must be stateless, but it might be a possibility.

            Jim Wooley
            [color=blue]
            > HI I think i have found the problem it is not my class because I have
            > rewritten the code from it to the main program and executed it and it
            > is creating the memory leek too.
            >
            > The problem is I have a 3rd party class that doesnt have a dispose
            > method. It has however a OpenConnection method and a CloseConnection
            > method but I call both of these and the memory leak is still there. I
            > even set the object to Nothing afterwards but still the memory leek
            > appears. Here is snippet of my code :
            >
            > Dim mobjUDConn As connection '# this object is declared in 3rd
            > party
            > DLL that is referenced
            > Dim mobjUDDB As connDatabase '# this object is declared in 3rd
            > party DLL that is referenced
            > Const mcMultiDelim As String = "ý"
            > Const mcColumnDelim As String = "þ"
            > '# XXX means REMOVED FOR SECURITY PURPOUSES
            > Dim sHost As String = "XXX.x.XXX. xx"
            > Dim sPort As Int32 = XXXX
            > Dim sUser As String = String.Empty = "admin"
            > Dim sPassword As String = String.Empty = "XXXXXXX"
            > Dim sDatabase As String = String.Empty = "XXX-XXXXXXXX"
            > '#SUB CONNECT
            > Dim ErrMsg As String
            > Try
            > If mobjUDConn Is Nothing Then
            > mobjUDConn = New connection
            > End If
            > If mobjUDConn.isCo nnected = False Then
            > With mobjUDConn
            > .Host = sHost
            > .Port = sPort
            > .User = sUser
            > .Password = sPassword
            > .Database = sDatabase
            > mobjUDConn.open ()
            > End With
            > End If
            > If mobjUDDB Is Nothing Then
            > mobjUDDB = New connDatabase
            > End If
            > If mobjUDDB.isConn ected = False Then
            > mobjUDDB = mobjUDConn.getD atabase
            > End If
            > ErrMsg = ""
            > Catch ex As Exception
            > ErrMsg = ex.Message
            > End Try
            > '# Thats it connection opened
            > '# Do reads / writes here
            > '##### Close Connection ####
            > mobjUDDB.close( )
            > '# ##### PROBLEM HERE #######
            > '# Problem is here mobjUDDB doesnt have a dispose method
            > mobjUDConn.clos e()
            > mobjUDConn.Disp ose()
            > mobjUDDB = Nothing
            > mobjUDConn = Nothing[/color]


            Comment

            • Brano

              #7
              Re: Memory Leaking in VB.NET

              Hi sounds good but I have never done anything like it. An example or
              link would be great...

              thanks


              Jim Wooley wrote:[color=blue]
              > You might want to consider wrapping the 3rd party class that is leaking with
              > the USING functionality (in 2005). Another option to try is possibly wrap
              > the call and set up a second app domain which can be sandboxed. You then
              > create and destroy the app domain, thereby isolating the leak and disposing
              > of it. Granted there is a performance penalty with the second app domain
              > and the second domain must be stateless, but it might be a possibility.
              >
              > Jim Wooley
              >[color=green]
              > > HI I think i have found the problem it is not my class because I have
              > > rewritten the code from it to the main program and executed it and it
              > > is creating the memory leek too.
              > >
              > > The problem is I have a 3rd party class that doesnt have a dispose
              > > method. It has however a OpenConnection method and a CloseConnection
              > > method but I call both of these and the memory leak is still there. I
              > > even set the object to Nothing afterwards but still the memory leek
              > > appears. Here is snippet of my code :
              > >
              > > Dim mobjUDConn As connection '# this object is declared in 3rd
              > > party
              > > DLL that is referenced
              > > Dim mobjUDDB As connDatabase '# this object is declared in 3rd
              > > party DLL that is referenced
              > > Const mcMultiDelim As String = "ý"
              > > Const mcColumnDelim As String = "þ"
              > > '# XXX means REMOVED FOR SECURITY PURPOUSES
              > > Dim sHost As String = "XXX.x.XXX. xx"
              > > Dim sPort As Int32 = XXXX
              > > Dim sUser As String = String.Empty = "admin"
              > > Dim sPassword As String = String.Empty = "XXXXXXX"
              > > Dim sDatabase As String = String.Empty = "XXX-XXXXXXXX"
              > > '#SUB CONNECT
              > > Dim ErrMsg As String
              > > Try
              > > If mobjUDConn Is Nothing Then
              > > mobjUDConn = New connection
              > > End If
              > > If mobjUDConn.isCo nnected = False Then
              > > With mobjUDConn
              > > .Host = sHost
              > > .Port = sPort
              > > .User = sUser
              > > .Password = sPassword
              > > .Database = sDatabase
              > > mobjUDConn.open ()
              > > End With
              > > End If
              > > If mobjUDDB Is Nothing Then
              > > mobjUDDB = New connDatabase
              > > End If
              > > If mobjUDDB.isConn ected = False Then
              > > mobjUDDB = mobjUDConn.getD atabase
              > > End If
              > > ErrMsg = ""
              > > Catch ex As Exception
              > > ErrMsg = ex.Message
              > > End Try
              > > '# Thats it connection opened
              > > '# Do reads / writes here
              > > '##### Close Connection ####
              > > mobjUDDB.close( )
              > > '# ##### PROBLEM HERE #######
              > > '# Problem is here mobjUDDB doesnt have a dispose method
              > > mobjUDConn.clos e()
              > > mobjUDConn.Disp ose()
              > > mobjUDDB = Nothing
              > > mobjUDConn = Nothing[/color][/color]

              Comment

              • Jim Wooley

                #8
                Re: Memory Leaking in VB.NET

                http://msdn2.microsoft.com/en-us/lib...appdomain.aspx
                [color=blue]
                > Hi sounds good but I have never done anything like it. An example or
                > link would be great...
                >
                > thanks
                >
                > Jim Wooley wrote:
                >[color=green]
                >> You might want to consider wrapping the 3rd party class that is
                >> leaking with
                >> the USING functionality (in 2005). Another option to try is possibly
                >> wrap the call and set up a second app domain which can be sandboxed.
                >> You then create and destroy the app domain, thereby isolating the
                >> leak and disposing
                >> of it. Granted there is a performance penalty with the second app
                >> domain and the second domain must be stateless, but it might be a
                >> possibility.
                >>
                >> Jim Wooley[/color][/color]


                Comment

                Working...