Solved

Memory Leak (handles) with system.net.sockets

Posted on 2008-10-10
4
399 Views
Last Modified: 2013-11-07
Hi,
I'm using visual studio 2K5 developing a visual basic.net application that communicates with devices attatched to our network which provide temperatures.

I have used additional development toos to debug the application and have found that the application is creating excessive handles and kills the server if left running for a period of time.

System.Net.Sockets.Socket::InitializeSockets      System.dll      0x0000005A is the leak, but am not sure on how to stop, its seems to be a leak within the .NET framework class.

Can someone help?


Public Class clsTempDevice
    Public Sub New(ByVal Device_IP_Address As String, ByVal Device_Port As String, ByVal Sleep_Period As Integer)
        Debug.Print("CREATING Object")
        Device_IPAddress = Device_IP_Address 'Here ne handle
        DevicePort = Device_Port
        SleepPeriod = Sleep_Period
    End Sub
 
    Public Sub GET_Temperatures()
 
        Dim DeviceIPAddress As IPAddress
        Dim EndPoint As IPEndPoint
        Dim DeviceSocket As Socket
 
        Wait(3000)
 
        Thread.Sleep(SleepPeriod)
 
        Dim strCommand As String = String.Empty
 
        'Data returned from the network socket.
        Dim strRecvString As String = String.Empty
 
        'Array to hold the split string.
        Dim strArray() As String
 
        'Number of bytes return from telnet socket (count)
        Dim intNumBytes As Integer = 0
 
        'Get the IP Address and the Port and create an IPEndpoint (ep)
        DeviceIPAddress = IPAddress.Parse(Device_IPAddress.Trim)
        EndPoint = New IPEndPoint(DeviceIPAddress, CType(DevicePort.Trim, Integer))
 
        'Set-up the socket.
        DeviceSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
 
        Dim RecvBytesBuffer(255) As Byte 'handle Here
 
        Try
            'Connect to socket
            DeviceSocket.Connect(EndPoint)
            Debug.Print(Device_IPAddress & " Is Online")
        Catch ex As SocketException
            DeviceSocket.Close()
            DEVICE_Offline()
            Debug.Print(ex.Message.ToString, " ----- " & ex.InnerException.ToString)
            Exit Sub
 
        End Try
        '-------------------------------------------
        Try
            Wait(2000)
 
            If DeviceSocket.Connected Then
 
                Do
                    intNumBytes = DeviceSocket.Receive(RecvBytesBuffer, _
                    RecvBytesBuffer.Length, SocketFlags.None)
                    '-------------------------------------------
                    strRecvString = strRecvString + _
                    Encoding.ASCII.GetString(RecvBytesBuffer, 0, intNumBytes)
                    '-------------------------------------------
                Loop While intNumBytes = 256 '256 'If less than 256 we at the end of the recv stream
 
                Debug.Print(strRecvString)
 
                Wait(1000)
                'DeviceSocket.Close()
                'DeviceSocket.Disconnect(False)
             
            End If
            '-------------------------------------------
            'Split returned string at carriage return
            strArray = Split(strRecvString, Chr(13))
 
            Dim iCounter As Integer
 
            'iterate through the array, check data is valid
            'and assign the appropriate probe number
 
            For iCounter = 0 To UBound(strArray)
 
                Debug.Print(strArray(iCounter))
 
                Dim strLocalString As String
                Dim StringLength As Integer
                '-------------------------------------------
                'Check 1st char in the string.
                If Microsoft.VisualBasic.Left(strArray(iCounter), 1) = "1" Then
 
                    strLocalString = strArray(iCounter)
                    StringLength = Len(strLocalString)
                    'Check len of string is greater than 3 to
                    'ensure reading is valid.
                    If (StringLength > 3) Then
                        Probe_1_TEMP = CStr(strArray(iCounter))
                    End If
 
                    'ASSIGN probe number to the property
                    Probe_Number = DeviceProbe.Probe1
                    '-------------------------------------------
                    'UPDATE the database.
                    SEND_UpdateMessage(Device_IPAddress, Probe_Number, Probe_1_TEMP)
                    '-------------------------------------------
                End If
                Wait(500)
                '-------------------------------------------
                If Microsoft.VisualBasic.Left(strArray(iCounter), 1) = "2" Then
 
                    strLocalString = strArray(iCounter)
                    StringLength = Len(strLocalString)
 
                    If (StringLength > 3) Then
                        Probe_2_TEMP = CStr(strArray(iCounter))
                    End If
 
                    Probe_Number = DeviceProbe.Probe2
                    '-------------------------------------------
                    SEND_UpdateMessage(Device_IPAddress, Probe_Number, Probe_2_TEMP)
                    '-------------------------------------------
                End If
                Wait(500)
                '-------------------------------------------
                If Microsoft.VisualBasic.Left(strArray(iCounter), 1) = "3" Then
 
                    strLocalString = strArray(iCounter)
                    StringLength = Len(strLocalString)
 
                    If (StringLength > 3) Then
                        Probe_3_TEMP = CStr(strArray(iCounter))
                    End If
 
                    Probe_Number = DeviceProbe.Probe3
 
                    SEND_UpdateMessage(Device_IPAddress, Probe_Number, Probe_3_TEMP)
 
                End If
                Wait(500)
                '-------------------------------------------
                If Microsoft.VisualBasic.Left(strArray(iCounter), 1) = "4" Then
 
                    strLocalString = strArray(iCounter)
                    StringLength = Len(strLocalString)
 
                    If (StringLength > 3) Then
                        Probe_4_TEMP = CStr(strArray(iCounter))
                    End If
 
                    Probe_Number = DeviceProbe.Probe4
                    '-------------------------------------------
                    SEND_UpdateMessage(Device_IPAddress, Probe_Number, Probe_4_TEMP)
                    '-------------------------------------------
                End If
                Wait(500)
            Next
 
            Debug.Print("DEVICE ON: " & Device_IPAddress)
            Debug.Print("Temperature Probe 1: " & Probe_1_TEMP)
            Debug.Print("Temperature Probe 2: " & Probe_2_TEMP)
            Debug.Print("Temperature Probe 3: " & Probe_3_TEMP)
            Debug.Print("Temperature Probe 4: " & Probe_4_TEMP)
 
            DeviceSocket.Close(1)
 
            DeviceIPAddress = Nothing
            EndPoint = Nothing
            DeviceSocket = Nothing
            strRecvString = Nothing
 
        Catch ex As Exception
            Debug.Print(ex.Message.ToString)
        End Try
 
    End Sub
 
    Public Sub Wait(ByVal PMillseconds As Integer)
        ' Function created to replace thread.sleep()
        ' Provides responsive main form without using threading.
 
        Dim TimeNow As DateTime
        Dim TimeEnd As DateTime
        Dim StopFlag As Boolean
 
        TimeEnd = Now()
        TimeEnd = TimeEnd.AddMilliseconds(PMillseconds)
        StopFlag = False
 
        While Not StopFlag
            TimeNow = Now()
            If TimeNow > TimeEnd Then
                StopFlag = True
            End If
            Application.DoEvents()
        End While
 
        ' Cleanup
        TimeNow = Nothing
        TimeEnd = Nothing
    End Sub
 
End Class

Open in new window

0
Comment
Question by:Schrader_Electronics
  • 2
4 Comments
 
LVL 26

Expert Comment

by:Anurag Thakur
ID: 22697363
The socket class if you think is the culprit class from where memory leaks are happening Implements a IDisposable Interface. It means that you can limit the scope of the socket class object by using in the following manner

Using DeviceSocket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
  ' operation on socket class object
End Using  'when the object goes out of scope its collected by the GC
0
 

Author Comment

by:Schrader_Electronics
ID: 22718652
Hi,
I changed the syntax using the "using " gramar, the handles are still being leaked.  The GC does not seen to have a reference to theese handles for some reason, its as if the IDisposable interface is not beining implemented.
0
 
LVL 26

Accepted Solution

by:
Anurag Thakur earned 500 total points
ID: 22718800
i was searching on the memory leak problem on google and came across a intresting link
http://www.pcreview.co.uk/forums/showpost.php?p=3664547&postcount=4
in this link there is a intresting discovery by a user comment no #4

also if you go through this article you will find that when ever the user has opened a socket the memory has increased by 8k though in .Net 1.1 but i am just thinking that the problem still remains
http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework/2005-05/msg00285.html

a workaround whihc is jsut coming to my mind is calling GC.Collect() after the socket is closed so that the memory is freed. If that does not work then only microsoft can help... all the best
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question