Утечка памяти в методе расширения Socket 'ReceiveAsync'! - PullRequest
0 голосов
/ 29 ноября 2018

У меня давно запущена сервисная программа на основе асинхронного сокета.Использование памяти постоянно увеличивается с течением времени, когда обнаруживается исправность (кратковременное подключение и отключение TCP-порта) другими устройствами.Я подозреваю, что некоторая память этого типа TCP-соединения не была освобождена.Итак, я сделал простую программу для проверки:

class Program
{
    static void Main(string[] args) => new Program().Start(args[0] == "server");

    private void Start(bool bStartServer)
    {
        if (bStartServer)
        {
            TcpListener tlToClient = TcpListener.Create(2868);
            tlToClient.Start();
            DoClientService(tlToClient);
            System.Console.WriteLine("start on port 2868...");
            for (int i = 0; i < 10; i++)
            {
                Console.ReadLine();
                GC.Collect();
            }
        }
        else
        {
            for (int i = 0; i < 50000; i++)
            {
                Socket s = new Socket(SocketType.Stream, ProtocolType.Tcp);
                s.Connect("127.0.0.1", 2868);
                s.Shutdown(SocketShutdown.Both);
                s.Close();
            }
            System.Console.WriteLine("all done");
            Console.ReadLine();
        }
    }

    static async Task DoClientService(TcpListener tlToClient)
    {
        while (true)
            Receive(await tlToClient.AcceptSocketAsync().ConfigureAwait(false));
    }

    static async Task Receive(Socket socket)
    {
        while (true)
        {
            await Task.Delay(50).ConfigureAwait(false);
            var read = await socket.ReceiveAsync(new ArraySegment<byte>(new byte[8192], 0, 8192), SocketFlags.None).ConfigureAwait(false);
            if (read == 0)
            {
                socket.Shutdown(SocketShutdown.Both);
                socket.Dispose();
                return;
            }
        }
    }
}

Как показывает код: после того, как сервер прослушивает порт 2868, тестовый клиент продолжит инициировать 50 000 TCP-подключений, и эти подключения будут закрыты после успешного подключения,Когда для буфера приема сервера установлено значение 8 192, после завершения теста серверу потребуется 800 МБ памяти.

Я подозреваю, что во внутренней реализации метода расширения Socket существует ошибка ReceiveAsync , которая приводит кв область освобождающего буфера не может быть освобождена.

Код был упрощен, он будет только проверять проблему утечки памяти.

Любая помощь будет оценена!

...