Solved

Memory Leak (handles) with system.net.sockets

Posted on 2008-10-10
4
391 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

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

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

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

809 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