none
c# program keeps increasing run time memory usages RRS feed

  • Question

  • it was at 782 MD yesterday and I left is running and not it is a  1.32gb.

    it keep increasing until the program crashing.

    how do I toubleshoot this ?

    here is a crash file it made

    https://www.dropbox.com/sh/nhwgqzos54xq1r7/AADmKZ6on5R8KHmsTKZkyeS5a?dl=0

     

    Wednesday, November 22, 2017 3:55 PM

Answers

  • No, you aren't cleaning things up properly. .NET uses a reference graph to determine what objects can and cannot be cleaned up. Since your SocketT2h owns a resource that needs to be cleaned up, it needs to implement IDisposable. Otherwise you're leaving the socket around longer than needed, hence a memory leak. You must implement this in SocketT2h otherwise you will continue to leak resources for a while and you'll see memory usage grow, until the GC. Note also that you're passing Socket to the helper, not SocketT2h. You don't actually seem to use the SocketT2h class at all beyond storing a list of them so you'll be working with Socket. If you also have code that has a SocketT2h instance then you can have an overload for RemoveSocket that is dramatically simpler.

    //This would probably be better as an extension method
    private SocketT2h GetClientSocket ( Socket socket )
    {
       //TODO: Verify it is found using the default equality    comparer for IPEndPoint
       return __ClientSockets.FirstOrDefault(s => s._Socket.RemoteEndPoint == socket._Socket.RemoteEndPoint);
    }
    
    //As would this
    private void RemoveSocket(Socket socket)
    {
       var existing = GetClientSocket(socket);
       if (existing != null)
          RemoveSocket(existing);
    }
    
    private void RemoveSocket ( SocketT2h socket )
    {
       _ClientSockets.Remove(socket);
       socket.Dispose();
    }

    You also don't need to be calling anything in a loop anymore. That is the entire purpose of having a helper method.

    private void ReceiveCallback(IAsyncResult ar)
    {
       Socket socket = (Socket)ar.AsyncState;
       if (socket.Connected)
       {
          int received;
          try
          {
             received = socket.EndReceive(ar);
          } catch (Exception)
          {
             RemoveSocket(socket);         
             AppendTextBox("Client : " + __ClientSockets.Count.ToString());
             return;
          };
    
          if (received != 0)
          {
             //This is inefficient, might want to stop
             //creating arrays everywhere and use a shared
             //buffer but note that this doesn't work with
             //multiple sockets as they will be using the
             //same buffer and stomping over each other...
             byte[] dataBuf = new byte[received];
             Array.Copy(_buffer, dataBuf, received);
                        
             int Registers_number = (((int)dataBuf[10] << 8) + (int)dataBuf[11]);
             int Message_Size = (Registers_number * 2) + 9;
             byte[] Message3 = new byte[Message_Size];
             TCPProcessing(dataBuf, Message3);
                     
             string reponse = string.Empty;
             if (CiscoCB.Checked == true)
             {
                string Stemp = BitConverter.ToString(Message3);
                AppendTextBox(Stemp + System.Environment.NewLine);
             }
    
             //Why are you removing it now?
             var clientSocket = GetClientSocket(socket);
             AppendTextBox("\n" + clientSocket_Name + "here: " );         
             Sendata(socket, Message3);
          } else
          {
             RemoveSocket(socket);
             AppendTextBox("Client: " + __ClientSockets.Count.ToString() );
          }
       }
       
      socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
    }
    


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Btb4198 Monday, November 27, 2017 8:47 PM
    Monday, November 27, 2017 5:05 PM
    Moderator

All replies

  • You will run a profiler and look at the memory usage. Using static analysis tools may help identify IDisposable objects you're not disposing of. If you're allocating large arrays then that will eat up memory as well. If you're using lots of static fields that store large objects, not cleaning up event  handlers, etc then the GC will also not be able to reclaim memory either.

    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, November 22, 2017 4:43 PM
    Moderator
  • Hello Btb4198,

    >>C# program keeps increasing run time memory usages

    The following is some common cause of  memory leaking. And also you should understand that leaks can happen in other pieces of .NET code that your applications rely on if you use some third-party lib.

    1. Static references
    2. Event with missing unsubscription
    3. Static event with missing unsubscription
    4. Dispose method not invoked
    5. Incomplete Dispose method
    6. using COM objects and not releasing them properly

    As for how to avoid memory leaking. You need to check your code and try to use some memory profiler.

    Sig[8].Name=Problem Signature 09
    Sig[8].Value=System.NullReferenceException

    You will find your exception type is System.ArgumentNullException  from your crash file. You should pay attention to the code where the error has thrown. There is a msdn article for error reporting.

    Sincerely,

    Fei Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, November 23, 2017 6:51 AM
    Moderator
  • I am sure the problem is something to so with the server I have...

    check out this code :

     private void SetupServer()
                {
                AppendTextBox("Starting server ...");
                _serverSocket.Bind(new IPEndPoint(IPAddress.Any, 502));
                _serverSocket.Listen(1);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);

                }
            private void AppceptCallback(IAsyncResult ar)
                {
                Socket socket = _serverSocket.EndAccept(ar);
                __ClientSockets.Add(new SocketT2h(socket));
              //  list_Client.Items.Add(socket.RemoteEndPoint.ToString());

                 AppendTextBox( "client: " + __ClientSockets.Count.ToString());
                 AppendTextBox( "Client connected. . .");
                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);
                }
            private void ReceiveCallback(IAsyncResult ar)
                {

                Socket socket = (Socket)ar.AsyncState;
                if (socket.Connected)
                    {
                    int received;
                    try
                        {
                        received = socket.EndReceive(ar);
                        }
                    catch (Exception)
                        {

                        for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (__ClientSockets[i]._Socket.RemoteEndPoint.ToString().Equals(socket.RemoteEndPoint.ToString()))
                                {
                                __ClientSockets.RemoveAt(i);
                                AppendTextBox("Client : " + __ClientSockets.Count.ToString());
                                }
                            }
                        return;
                        }
                    if (received != 0)
                        {
                        byte[] dataBuf = new byte[received];
                        Array.Copy(_buffer, dataBuf, received);

                        int Registers_number = (((int)dataBuf[10] << 8) + (int)dataBuf[11]);
                        int Message_Size = (Registers_number * 2) + 9;
                        byte[] Message3 = new byte[Message_Size];
                        TCPProcessing(dataBuf, Message3);


                        string reponse = string.Empty;

                        if (CiscoCB.Checked == true)
                            {
                            string Stemp = BitConverter.ToString(Message3);
                            AppendTextBox(Stemp + System.Environment.NewLine);
                            }

                        for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (socket.RemoteEndPoint.ToString().Equals(__ClientSockets[i]._Socket.RemoteEndPoint.ToString()))
                                {
                                 AppendTextBox("\n" + __ClientSockets[i]._Name + ": " );
                                }
                            }
                       // reponse = "server da nhan" + text;
                        Sendata(socket, Message3);
                        }
                    else
                        {
                        for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (__ClientSockets[i]._Socket.RemoteEndPoint.ToString().Equals(socket.RemoteEndPoint.ToString()))
                                {
                                __ClientSockets.RemoveAt(i);
                                AppendTextBox("Client: " + __ClientSockets.Count.ToString() );
                                }
                            }
                        }
                    }

                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
                }
            void Sendata(Socket socket, byte[] data)
                {
              //  byte[] data = Encoding.ASCII.GetBytes(noidung);
                socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);
                }
            private void SendCallback(IAsyncResult AR)
                {
                Socket socket = (Socket)AR.AsyncState;
                socket.EndSend(AR);
                }

    I did not have this problem until I added to code in, so that is why I am sure it is the problem.

    the device that connect to this program, I think the problem is not deleting old connection, but I am not sure

    Monday, November 27, 2017 1:22 PM
  • k update, when i unplug the Ethernet wire it does not disconnect. It does when I connect the program to a computer that run a modbus client, but then i connect to the cisco modem it does not. I think the cisco modem make a new connection every time it pull data. I think the old connects are not being removed. any ideas ?
    Monday, November 27, 2017 2:46 PM
  • Please do not post code directly in your responses. There is a Code Block button in the editor that allows you to post code blocks that render properly in posts.

    Socket implements IDisposable. Each time you get one you need to clean it up when you're done with it, assuming you won't need it anymore. Looking at your code, it appears you are storing your sockets in a list. When you receive data, if an exception occurs you are removing the socket from the list but you never dispose of it. You need to dispose of the socket to release the resources. Of course you'd need a lot of errors to occur in order to eat up the memory you're talking about (or a lot of drops) so there is probably more than just this case you need to evaluate. I notice you're doing this same code later on as well. You really need to wrap this in a method that is more easy to manage.

    void RemoveSocket ( Socket socket )
    {
       //Find it - I have no idea what a SocketT2h is so I'm assuming you're using a normal Socket instead
       //Remove should work since it does an equality comparison
       //and there should be only 1 socket instance  
       _ClientSockets.Remove(socket);
       
       //But here's the long way - assuming IPEndPoint has an 
       //equality comparer that works here
       var existing = _ClientSockets.FirstOrDefault(s => s.RemoteEndPoint == socket.RemoteEndPoint);
       if (existing != null)
          _ClientSockets.Remove(existing);
    
       //Clean it up 
       socket.Dispose();
       //existing?.Dispose();
    }
    A memory profiler will better be able to identify where the leak is though. You really need to run one.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, November 27, 2017 2:56 PM
    Moderator
  •   private byte[] _buffer = new byte[1024];
            public List<SocketT2h> __ClientSockets { get; set; }
            List<string> _names = new List<string>();
            private Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    the code block button is not coming up..

    i can see HTML then blank then the pic box

    Monday, November 27, 2017 3:13 PM
  •  public class SocketT2h
            {
            public Socket _Socket { get; set; }
            public string _Name { get; set; }
            public SocketT2h(Socket socket)
                {
                this._Socket = socket;
                }
            }
    Monday, November 27, 2017 3:14 PM
  • I am not sure why,

    but then I add your code, I get this error 

    Monday, November 27, 2017 3:18 PM
  • the error is

    Error 17 The name '_ClientSockets' does not exist in the current context

    Monday, November 27, 2017 3:19 PM
  • ok I changed your code to this :

            private void RemoveSocket(SocketT2h socket)
                {
                //Find it - I have no idea what a SocketT2h is so I'm assuming you're using a normal Socket instead
                //Remove should work since it does an equality comparison
                //and there should be only 1 socket instance  
             
                __ClientSockets.Remove(socket);
                //But here's the long way - assuming IPEndPoint has an 
                //equality comparer that works here
                var existing = _ClientSockets._Socket.FirstOrDefault(s => s.RemoteEndPoint == socket._Socket.RemoteEndPoint);
                if (existing != null)
                    _ClientSockets.Remove(existing);
    
                //Clean it up 
                socket._Socket.Dispose();
                //existing?.Dispose();
                }
            

    but it is still not liking existing = _ClientSockets._socket....

    it says 

    Error 16 The name '_ClientSockets' does not exist in the current context
    Monday, November 27, 2017 3:35 PM
  • _ClientSockets is a list of SocketT2h I assume. _ClientSockets._Socket doesn't exist in a list. Remove the _Socket logic. But that code isn't going to work at all with your SocketT2h class. As I mentioned, I was ignoring your SocketT2h class and just assuming a Socket. To account for your SocketT2h class you'd have to update the lambda to dereference the Socket property on s. But you cannot just blindly copy the code I gave you. As the comments said, you need to use the code that works for your scenario, not all of it. If you're determined to stick with SocketT2h then the first Remove call won't work as you aren't working with Socket anymore. The FirstOrDefault will work but you need to update the code to account for your custom type.

    var existing = _ClientSockets.FirstOrDefault(s => s.Socket.RemoteEndpoint == socket.Socket.RemoteEndpoint);

    To get the socket to dispose, since your SocketT2h is responsible for its lifetime, SocketT2h needs to implement IDisposable as well and clean up the socket. Then you'd just use existing?.Dispose() instead.

    public class SocketT2h : IDisposable
    {
       ~SocketT2h ()
       {
          Dispose(false);
       }
    
       public void Dispose ()
       {
          Dispose(true);
          GC.SuppressFinalize(this);
       }
    
       protected virtual void Dispose ( bool disposing )
       {
          if (disposing) 
          {
             _Socket?.Dispose();
             _Socket = null;
          };
       }
    }
    Read here on how to properly implement IDisposable.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, November 27, 2017 3:55 PM
    Moderator
  • can I just do this :

    private void RemoveSocket(SocketT2h socket)
                {
                //Find it - I have no idea what a SocketT2h is so I'm assuming you're using a normal Socket instead
                //Remove should work since it does an equality comparison
                //and there should be only 1 socket instance  
             
                __ClientSockets.Remove(socket);
                //But here's the long way - assuming IPEndPoint has an 
                //equality comparer that works here
                var existing = __ClientSockets.FirstOrDefault(s => s._Socket.RemoteEndPoint == socket._Socket.RemoteEndPoint);
                /*if (existing != null)
                    _ClientSockets.Remove(existing); */
    
                //Clean it up 
                socket._Socket.Dispose();
                //existing?.Dispose();
                }

    since SocketT2h has a socket in it ?

    Monday, November 27, 2017 4:03 PM
  • ok add that functions in two places: 

      
     private void ReceiveCallback(IAsyncResult ar)
                {
    
                Socket socket = (Socket)ar.AsyncState;
                if (socket.Connected)
                    {
                    int received;
                    try
                        {
                        received = socket.EndReceive(ar);
                        }
                    catch (Exception)
                        {
                      
                        for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (__ClientSockets[i]._Socket.RemoteEndPoint.ToString().Equals(socket.RemoteEndPoint.ToString()))
                                {
                                RemoveSocket(__ClientSockets[i]);
                                __ClientSockets.RemoveAt(i);
                                
                               // __ClientSockets.
                                AppendTextBox("Client : " + __ClientSockets.Count.ToString());
                                }
                            }
                        return;
                        }
                    if (received != 0)
                        {
                        byte[] dataBuf = new byte[received];
                        Array.Copy(_buffer, dataBuf, received);
                        
                        int Registers_number = (((int)dataBuf[10] << 8) + (int)dataBuf[11]);
                        int Message_Size = (Registers_number * 2) + 9;
                        byte[] Message3 = new byte[Message_Size];
                        TCPProcessing(dataBuf, Message3);
                     
    
                        string reponse = string.Empty;
    
                        if (CiscoCB.Checked == true)
                            {
                            string Stemp = BitConverter.ToString(Message3);
                            AppendTextBox(Stemp + System.Environment.NewLine);
                            }
    
                        for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (socket.RemoteEndPoint.ToString().Equals(__ClientSockets[i]._Socket.RemoteEndPoint.ToString()))
                                {
                                 AppendTextBox("\n" + __ClientSockets[i]._Name + "here: " );
                                }
                            }
                       // reponse = "server da nhan" + text;
                        Sendata(socket, Message3);
                        }
                    else
                        {
                        for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (__ClientSockets[i]._Socket.RemoteEndPoint.ToString().Equals(socket.RemoteEndPoint.ToString()))
                                {
                                 RemoveSocket(__ClientSockets[i]);
                                __ClientSockets.RemoveAt(i);
                                AppendTextBox("Client: " + __ClientSockets.Count.ToString() );
                                }
                            }
                        }
                    }
    
                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
                }

    Monday, November 27, 2017 4:16 PM
  • No, you aren't cleaning things up properly. .NET uses a reference graph to determine what objects can and cannot be cleaned up. Since your SocketT2h owns a resource that needs to be cleaned up, it needs to implement IDisposable. Otherwise you're leaving the socket around longer than needed, hence a memory leak. You must implement this in SocketT2h otherwise you will continue to leak resources for a while and you'll see memory usage grow, until the GC. Note also that you're passing Socket to the helper, not SocketT2h. You don't actually seem to use the SocketT2h class at all beyond storing a list of them so you'll be working with Socket. If you also have code that has a SocketT2h instance then you can have an overload for RemoveSocket that is dramatically simpler.

    //This would probably be better as an extension method
    private SocketT2h GetClientSocket ( Socket socket )
    {
       //TODO: Verify it is found using the default equality    comparer for IPEndPoint
       return __ClientSockets.FirstOrDefault(s => s._Socket.RemoteEndPoint == socket._Socket.RemoteEndPoint);
    }
    
    //As would this
    private void RemoveSocket(Socket socket)
    {
       var existing = GetClientSocket(socket);
       if (existing != null)
          RemoveSocket(existing);
    }
    
    private void RemoveSocket ( SocketT2h socket )
    {
       _ClientSockets.Remove(socket);
       socket.Dispose();
    }

    You also don't need to be calling anything in a loop anymore. That is the entire purpose of having a helper method.

    private void ReceiveCallback(IAsyncResult ar)
    {
       Socket socket = (Socket)ar.AsyncState;
       if (socket.Connected)
       {
          int received;
          try
          {
             received = socket.EndReceive(ar);
          } catch (Exception)
          {
             RemoveSocket(socket);         
             AppendTextBox("Client : " + __ClientSockets.Count.ToString());
             return;
          };
    
          if (received != 0)
          {
             //This is inefficient, might want to stop
             //creating arrays everywhere and use a shared
             //buffer but note that this doesn't work with
             //multiple sockets as they will be using the
             //same buffer and stomping over each other...
             byte[] dataBuf = new byte[received];
             Array.Copy(_buffer, dataBuf, received);
                        
             int Registers_number = (((int)dataBuf[10] << 8) + (int)dataBuf[11]);
             int Message_Size = (Registers_number * 2) + 9;
             byte[] Message3 = new byte[Message_Size];
             TCPProcessing(dataBuf, Message3);
                     
             string reponse = string.Empty;
             if (CiscoCB.Checked == true)
             {
                string Stemp = BitConverter.ToString(Message3);
                AppendTextBox(Stemp + System.Environment.NewLine);
             }
    
             //Why are you removing it now?
             var clientSocket = GetClientSocket(socket);
             AppendTextBox("\n" + clientSocket_Name + "here: " );         
             Sendata(socket, Message3);
          } else
          {
             RemoveSocket(socket);
             AppendTextBox("Client: " + __ClientSockets.Count.ToString() );
          }
       }
       
      socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
    }
    


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Btb4198 Monday, November 27, 2017 8:47 PM
    Monday, November 27, 2017 5:05 PM
    Moderator
  • ok so update,

    I redid the code to this :

     private void SetupServer()
                {
                AppendTextBox("Starting server ...");
                _serverSocket.Bind(new IPEndPoint(IPAddress.Any, 502));
                _serverSocket.Listen(1);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);
                
                }
            private void AppceptCallback(IAsyncResult ar)
                {
                Socket socket = _serverSocket.EndAccept(ar);
                __ClientSockets.Add(socket);
              //  list_Client.Items.Add(socket.RemoteEndPoint.ToString());
    
                 AppendTextBox( "client: " + __ClientSockets.Count.ToString());
                 AppendTextBox( "Client connected. . .");
                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);
                }
    
            private void RemoveSocket(Socket socket)
                {
                //Find it - I have no idea what a SocketT2h is so I'm assuming you're using a normal Socket instead
                //Remove should work since it does an equality comparison
                //and there should be only 1 socket instance  
             
                __ClientSockets.Remove(socket);
                //But here's the long way - assuming IPEndPoint has an 
                //equality comparer that works here
                var existing = __ClientSockets.FirstOrDefault(s => s.RemoteEndPoint == socket.RemoteEndPoint);
                /*if (existing != null)
                    _ClientSockets.Remove(existing); */
    
                //Clean it up 
                socket.Dispose();
                //existing?.Dispose();
                }
            
            private void ReceiveCallback(IAsyncResult ar)
                {
    
                Socket socket = (Socket)ar.AsyncState;
                if (socket.Connected)
                    {
                    int received;
                    try
                        {
                        received = socket.EndReceive(ar);
                        }
                    catch (Exception)
                        {
                      
                        for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (__ClientSockets[i].RemoteEndPoint.ToString().Equals(socket.RemoteEndPoint.ToString()))
                                {
                                RemoveSocket(__ClientSockets[i]);
                                __ClientSockets.RemoveAt(i);
                                
                               // __ClientSockets.
                                AppendTextBox("Client : " + __ClientSockets.Count.ToString());
                                }
                            }
                        return;
                        }
                    if (received != 0)
                        {
                        byte[] dataBuf = new byte[received];
                        Array.Copy(_buffer, dataBuf, received);
                        
                        int Registers_number = (((int)dataBuf[10] << 8) + (int)dataBuf[11]);
                        int Message_Size = (Registers_number * 2) + 9;
                        byte[] Message3 = new byte[Message_Size];
                        TCPProcessing(dataBuf, Message3);
                     
    
                        string reponse = string.Empty;
    
                        if (CiscoCB.Checked == true)
                            {
                            string Stemp = BitConverter.ToString(Message3);
                            AppendTextBox(Stemp + System.Environment.NewLine);
                            }
    
                        /*for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (socket.RemoteEndPoint.ToString().Equals(__ClientSockets[i].RemoteEndPoint.ToString()))
                                {
                               //  AppendTextBox("\n" + "here: " );
                                }
                            } */
                       // reponse = "server da nhan" + text;
                        Sendata(socket, Message3);
                        }
                    else
                        {
                        for (int i = 0; i < __ClientSockets.Count; i++)
                            {
                            if (__ClientSockets[i].RemoteEndPoint.ToString().Equals(socket.RemoteEndPoint.ToString()))
                                {
                                 RemoveSocket(__ClientSockets[i]);
                                __ClientSockets.RemoveAt(i);
                                AppendTextBox("Client: " + __ClientSockets.Count.ToString() );
                                }
                            }
                        }
                    }
    
                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
                }
            void Sendata(Socket socket, byte[] data)
                {
              //  byte[] data = Encoding.ASCII.GetBytes(noidung);
                socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);
                }
            private void SendCallback(IAsyncResult AR)
                {
                Socket socket = (Socket)AR.AsyncState;
                socket.EndSend(AR);
                }
         

    the program has been running since 11:05 AM CST to now 1:36 PM, the memory usages started off at 742MB and is now 781MB .

    I did remove the class SocketT2h. I really did not need it, but  I am still having leaks..

    ok I print out the number of client connected but It said only one client has been connected so for.

    so now I am not sure what to do.

    Monday, November 27, 2017 7:39 PM
  • ok CoolDadTX I changed my code to what you have in your post and it is working ...

    memory usages go up and down like normal. I just saw 716 MB and it have been running for a over a hour. 

    so how did you fix it ?

    why is your code working ?

    oh also I did remove the socketT2h class:

     private void SetupServer()
                {
                AppendTextBox("Starting server ...");
                _serverSocket.Bind(new IPEndPoint(IPAddress.Any, 502));
                _serverSocket.Listen(1);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);
                
                }
            private void AppceptCallback(IAsyncResult ar)
                {
                Socket socket = _serverSocket.EndAccept(ar);
                __ClientSockets.Add(socket);
              //  list_Client.Items.Add(socket.RemoteEndPoint.ToString());
    
                 AppendTextBox( "client: " + __ClientSockets.Count.ToString());
                 AppendTextBox( "Client connected. . .");
                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);
                }
    
            private void RemoveSocket(Socket socket)
                {
                //Find it - I have no idea what a SocketT2h is so I'm assuming you're using a normal Socket instead
                //Remove should work since it does an equality comparison
                //and there should be only 1 socket instance  
             
                __ClientSockets.Remove(socket);
                //But here's the long way - assuming IPEndPoint has an 
                //equality comparer that works here
                var existing = __ClientSockets.FirstOrDefault(s => s.RemoteEndPoint == socket.RemoteEndPoint);
                if (existing != null)
                    __ClientSockets.Remove(existing); 
    
                //Clean it up 
                socket.Dispose();
                //existing?.Dispose();
                }
            
            private void ReceiveCallback(IAsyncResult ar)
                {
    
                Socket socket = (Socket)ar.AsyncState;
                if (socket.Connected)
                    {
                    int received;
                    try
                        {
                        received = socket.EndReceive(ar);
                        }
                    catch (Exception)
                        {
                      RemoveSocket(socket);         
                      AppendTextBox("Client : " + __ClientSockets.Count.ToString());
                        return;
                        };
                    if (received != 0)
                        {
                        byte[] dataBuf = new byte[received];
                        Array.Copy(_buffer, dataBuf, received);
                        
                        int Registers_number = (((int)dataBuf[10] << 8) + (int)dataBuf[11]);
                        int Message_Size = (Registers_number * 2) + 9;
                        byte[] Message3 = new byte[Message_Size];
                        TCPProcessing(dataBuf, Message3);
                        string reponse = string.Empty;
                        if (CiscoCB.Checked == true)
                            {
                            string Stemp = BitConverter.ToString(Message3);
                            AppendTextBox(Stemp + System.Environment.NewLine);
                            }
    
                       
                       // reponse = "server da nhan" + text;
                        Sendata(socket, Message3);
                        }
                    else
                        {
                        RemoveSocket(socket);
                        AppendTextBox("Client: " + __ClientSockets.Count.ToString());
                        }
                    }
    
                socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
                }
            void Sendata(Socket socket, byte[] data)
                {
              //  byte[] data = Encoding.ASCII.GetBytes(noidung);
                socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
                _serverSocket.BeginAccept(new AsyncCallback(AppceptCallback), null);
                }
            private void SendCallback(IAsyncResult AR)
                {
                Socket socket = (Socket)AR.AsyncState;
                socket.EndSend(AR);
                }
         



    Monday, November 27, 2017 9:11 PM
  • Removing the SocketT2h would have solved a lot of issues. .NET apps will allocate memory as the app runs. Under normal usage memory will increase until it hits a threshold or runs low on memory. At that point the GC will run and free up unused memory. Rinse and repeat. So over the life of an app memory will go through periods of increase and then drop. This is normal. It is only if memory is jumping in large chunks or memory is never going back down that you have issues.

    Provided you're disposing of IDisposable objects when you're done and not holding onto large arrays forever then the GC will generally clean everything up properly.


    Michael Taylor http://www.michaeltaylorp3.net

    Monday, November 27, 2017 9:15 PM
    Moderator
  • ok  bad news, the program crash again  because of low memory. I thought it was working because it looked good on Monday, but it crashed today.

    so I guess the leaked is still in the code...

    anything ideas ?


    • Edited by Btb4198 Thursday, November 30, 2017 12:39 AM
    Wednesday, November 29, 2017 8:07 PM