2017-08-17 197 views
2

我正在做我的第一步与C#中的异步/等待,为此我想写一个简单的TCP服务器接收简单的字符串(现在)。 因此,我设置了一个Windows服务,其中包含一个循环,用于监听传入连接,接受这些连接并关闭套接字(我打算将字符串写入日志文件或其他东西,但这必须等到问题出现为止我即将形容解决)。异步TCP服务器(Windows服务)内存泄漏

无论如何,问题是,在网络上收到一些字符串后,我的服务正在占用内存,而这些内存在以后不会发布。当我启动服务并且没有连接时,该过程需要4.716K。当连接被接受时,这个数量会增加(正如我所预料的那样),但是这些资源看起来并不会被释放......

可能我忽略了某些东西,但是我找不到解决方案(尽管“项目”包含只有几行代码现在),因此我将非常感谢您的帮助,伙计们:/

这些都是启动/关闭事件处理程序:

protected override void OnStart(string[] args) 
{ 
    this.listener = new TcpListener(IPAddress.Any, 7777); 
    this.listener.Start(); 

    this.worker = new Thread(StartServer); 
    this.worker.Start(); 
} 

protected override void OnStop(string[] args) 
{ 
    this.serviceIsRunning = false; 
    this.worker.Join(); 

    // TODO: Cancellation token maybe? 
} 

而这个服务器循环:

private async void ServerStart(object arguments) 
{ 
    while (serviceIsRunning) 
    { 
     TcpClient client = await listener.AcceptTcpClientAsync(); 
     Task requestTask = HandleRequest(client); 
    } 

    this.listener.Stop(); 
} 

连接处理器:

private async Task HandleRequest(TcpClient client) 
{ 
    using (var stream = new StreamReader(client.GetStream(), Encoding.UTF8)) 
    { 
     // Do something with it 
     string request = await stream.ReadToEndAsync(); 
    } 

    // Gracefully close connection 
    client.Close(); 
} 

谢谢!

+3

4.7KB(你的意思是MB?)使用过的内存没有多少说明,因为GC可能认为它不值得运行一个集合。您可以尝试手动添加'GC.Collect()'调用并查看是否释放内存,但是在分析应用程序并查看是否有任何对象位于手动强制集合后不再使用的情况下(他们的参考树一直到应用程序根目录)。 – easuter

回答

2

内存使用率很低。我已经看到垃圾回收器等待,直到我有2个千兆字节的内存被3D模型/图像消耗后才会运行。如果随着时间的推移观察应用程序的行为,您会在大量运行中看到高峰和低谷。我建议两个实验。

  1. 启动任务管理器,在怠速运行过程几秒钟,然后从服务器发送数据的一些大的爆发,使得该请求是围绕100-1000倍进行处理,然后让它继续开了几秒钟后关闭它。内存使用应该返回到您的应用程序打开之前的位置。

  2. 遵循几乎相同的过程,但是这次在处理请求(GC.Collect())后调用垃圾回收器。检查您的内存使用情况是否与此次不同。

如果这不能按预期工作,请尝试创建和销毁您的TCP服务器类。内存使用情况应该恢复正常。这将问题隔离到您的班级或垃圾收集器。