异步套接字高内存使用率和可能的泄漏

时间:2017-10-20 19:39:12

标签: c# sockets asyncsocket

我正在重写服务器应用程序,并且对应用程序的内存使用情况感到困惑。早期版本使用TcpListener编写,而新版本使用Socket。这主要是出于性能和稳定性的原因,这个问题仅次于这个问题甚至是这个问题。

如前所述,AcceptAsyncSendAsyncReceiveAsync的所有内容都非常异步。最重要的是,我使用ThreadPool.QueueUserWorkItem来执行实用程序任务,例如AcceptAsync的初始启动并保持下一个AcceptAsync排队,处理后的调用将写回Socket 1}},并且调用清理断开连接的客户端。此外,我还会使用BeginInvokeEndInvoke触发一系列事件。

对这些断开连接以及数据可用性的主要驱动程序的检测由我调用AvailabilityNotifier的自定义类处理,该类在ReceiveAsync上达到峰值并检测到SocketAsyncEventArgs.BytesTransferred为零会触发Disconnect事件。

应用程序的吞吐量很好,并且由于System.Collections.Concurrent对象的健康使用,几乎为零(相对而言)锁争用。然而,它依附于记忆中,就像一只捕食者一样紧紧抓住了。

我已经调试以验证我的内部集合是否已被清除,客户端套接字正在被关闭和处理,并利用缓冲池而不是为每次读取创建新的缓冲区。运行最终执行1,000个连接(100个并发)并发送/接收100,000个消息的测试应用程序会使服务器进程内存膨胀到大约800 MB,即使Windows清除了可能发生的任何TIME_WAIT,它也永远不会停止运行。我知道,由于你可以在下面链接的github中看到大量的ObjectDisposedException和null异常catch块,所以偶像代码会被触发。

我说没有引用代码的所有内容因为这里的帖子很长,所以这里有一个github:https://github.com/hoagsie/TcpServer。如果您想自己运行Program.csClientProgram.cs,则会提供NetworkServer.csAvailabilityNotifier.cs,但主要操作位于SocketAsyncEventArgsDispose。我运行的示例服务器也有一个与之对话的WCF服务,但它只是标准的WCF项目,几乎没有任何修改。我只是需要它来匹配一个示例场景。

我也不确定它在某种程度上是否重要,但我确实在x64模式而不是AnyCPU / x86中构建它。这主要是针对目标服务器上的资源消耗机会,但我没有注意到x86或x64中与此问题有关的行为差异。

修改

一位同事在Visual Studio中指出了快照工具。我之前从未见过它,它显示的东西与我使用的东西不同,这是dotTrace。它指出围绕IDisposable对象的大量分配是有道理的,但他们不断建造和建造。我再次查看了其成员列表,发现它有一个customer方法。我的问题已经消失了。我没有意识到这是一个customer_membership_status对象。

1 个答案:

答案 0 :(得分:0)

一位同事在Visual Studio中指出了快照工具。我之前从未见过它,它显示的东西与我使用的东西不同,这是dotTrace。它指出围绕SocketAsyncEventArgs对象的大量分配是有道理的,但他们不断建造和建造。我再次查看了其成员列表,发现它有一个Dispose方法。我的问题已经消失了。我没有意识到这是一个IDisposable对象。