首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >套接字扩展方法'ReceiveAsync‘的内存泄漏!

套接字扩展方法'ReceiveAsync‘的内存泄漏!
EN

Stack Overflow用户
提问于 2018-11-29 10:17:21
回答 1查看 687关注 0票数 3

我有一个基于异步套接字的长期运行的服务程序.当其他设备检测到它的健康状况(短时间TCP端口连接和断开)时,它的内存使用量会随着时间的推移而不断增加。我怀疑这类TCP连接的一些内存还没有释放。所以我做了一个简单的验证程序:

代码语言:javascript
复制
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 is内存。

我怀疑套接字扩展方法ReceiveAsync的内部实现存在缺陷,导致缓冲区无法释放。

代码已经简化,它只会测试内存泄漏问题。

任何帮助都将不胜感激!

EN

回答 1

Stack Overflow用户

发布于 2020-03-13 21:40:01

您应该创建一个缓冲区并重用它。垃圾收集并不咄咄逼人,这就解释了泄漏的原因。更具体地说,这一行var Buffer = new ArraySegment<byte>(new byte[8192], 0, 8192);

应该退出while循环,并将其传递到ReciveAsync中。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53536647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档