2012-09-24 13 views
3

특정 포트에서 수신 대기중인 서버 응용 프로그램을 작성하려고합니다. 장치가 해당 포트를 공격하기를 기다리고 있습니다. 장치가 30 초마다 연결됩니다. 장치가 연결되면 장치가 MAC 주소를 보냅니다. 그러나 문제는 기억이 계속 증가하고 결코 자유 로워지지 않는다는 것입니다.C# 소켓 응용 프로그램에서 메모리 누수가 발생했습니다.

class Server 
{ 
    Object threadLock = new Object(); 
    bool stopListening = false; 
    Socket clientSocket = null; 

    private void StartDeviceListener() 
    { 

     try 
     { 
      // create the socket 
      clientSocket = new Socket(AddressFamily.InterNetwork, 
              SocketType.Stream, 
              ProtocolType.Tcp); 

      // bind the listening socket to the port 
      IPEndPoint ep1 = new IPEndPoint(IPAddress.Any, 60000); 
      clientSocket.LingerState = new LingerOption(false, 0); 

      clientSocket.Bind(ep1); 
      clientSocket.Listen(10); //Waiting for Devices to connect. 

      do 
      { 
       // start listening 
       Console.WriteLine("Waiting for device connection on {0}....", 60000); 
       Socket deviceSocket = clientSocket.Accept(); 
       //Console.WriteLine(deviceSocket. 
       #region ThreadPool 

       // ThreadPool.QueueUserWorkItem(ProcessRequest, (Object)deviceSocket); 
       Thread ts = new Thread(ProcessRequest); 
       ts.IsBackground = true; 
       ts.Start((Object)deviceSocket); 
       ts.Join(); 
       #endregion 
      } while (!stopListening); 

     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("exception... : " + ex.Message); 
      StartDeviceListener(); 
     } 

     finally 
     { 
      if (clientSocket != null) { clientSocket.Close(); clientSocket = null; } 
     } 

    } 

    public void Stop() 
    { 
     try 
     { 
      stopListening = true; 
      if (clientSocket != null) 
      { 
       clientSocket.Disconnect(false); 
       clientSocket = null; 
      } 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("exception : " + ex.Message); 
     } 
    } 


    void ProcessRequest(Object args) 
    { 
     using (Socket deviceSocket = args as Socket) 
     { 
      try 
      { 

       //lock the thread while we are creating the client IO Interface Manager 
       lock (threadLock) 
       { 
        byte[] readBuffer = new byte[1024]; 
        // Read from buffer 
        int count = deviceSocket.Receive(readBuffer, 0, readBuffer.Length, SocketFlags.None); 
        String macAddress = "";//mac address sent by the device: 
        if (count > 0) 
        { 
         Encoding encoder = Encoding.ASCII; 
         int size = 0; 
         while (count > 0) 
         { 
          size += count; 
          // get string 
          macAddress += encoder.GetString(readBuffer, 0, count).Trim(); 
          // Read from buffer 
          count = 0; 
         } 
         Console.WriteLine(string.Format("{0} trying to connect....", macAddress)); 
        } 
        deviceSocket.Close(); 
        readBuffer = null; 
       } 
       //threadLock = null; 

      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("exception : " + ex.Message); 
      } 
     } 
     args = null; 
    } 

    public void Start() 
    { 
     StartDeviceListener(); 
    } 
}` 

Initial Server running

Initial Memory Consumption

Device ConnectingMemory Consumption After Initial Connection

Device Connection

Memory Consumption After Multiple Connection

+0

가비지 수집기를 수동으로 시작하려 했습니까? http://msdn.microsoft.com/ru-ru/library/system.gc.collect.aspx –

+4

@Dimitry : 수동으로 가비지 수집을 시작해야하는 경우 매우 나쁘거나 이상한 일을합니다. 가비지 콜렉터를 직접 호출하는 것은 예외입니다. – Falanwe

+0

Falanwe : 실험 할 때 그것을하는 것이 좋습니다. 메모리 누수 찾기는 실험적입니다. 나는 가비지 컬렉터가 아직 실행되지 않았기 때문에 메모리가 계속 증가하는 것을 의미했다. –

답변

1

하지만 문제는 메모리가 계속 증가하고 결코 해제되지 않는다는 것입니다.

여전히 메모리 누수와는 거리가 멀다. 당신은 아마 존재하지 않는 문제를 쫓고 있습니다.

마지막으로 10MB의 작업 세트가 남아 있습니다. 실제로는 0입니다.
정말로 메모리 문제를 찾고 해결하려면 프로파일 러를 사용하십시오.

+0

단 하나의 장치를 연결하면 문제가 없습니다. 하지만 문제를 연결하려고하는 4K -5K 장치가 확대되면 확대됩니다. – batrulz

+0

얼마만큼 확대 되었습니까? OOM 예외가 발생 했습니까? –

+0

서버를 하루 동안 작동 시키면 1GB까지 계속 증가합니다. 나는 그 이후에 어떤 장치 에나 연결할 수 있습니다. 그래서 하루에 한 번 m/c와 서버를 다시 시작하는 예약 된 작업이 있습니다. – batrulz

관련 문제