我有一个简单的.net 3.5sp1窗口应用程序(在C#中)充当UDP服务器。它监听端口,接收来自端点的数据,然后将接收到的数据重新发送到另一个端点(即中继,用于实况广播数据流)。我所经历的是在连接达到约20分钟后,它开始恶化。另外我注意到它每秒吞噬大约50-100K的内存,这在GC之后从未得到释放。我必须关闭应用程序并重新启动它。不好。我已经缩小的问题下面的代码,它不重传向另一侧:SendToAsync内存泄漏?
var sendBuffer = new byte[readCount];
Array.Copy(readData, sendBuffer, readCount);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = p.EP;
args.SetBuffer(sendBuffer, 0, sendBuffer.Length);
SwitchWindow.LineSocket.SendToAsync(args);
有没有人有与SendToAsync内存泄漏的经验吗?
UPDATE:
我实例化时,插座被初始化的状态对象(仅做一次)。状态对象有一个名为“缓冲区”的属性,它是一个字节数组。我收到的数据异步从插座像这样:
private void beginReceiveData(ref MessageState state)
{
var ipeSender = new IPEndPoint(IPAddress.Any, 0);
var epSender = (EndPoint)ipeSender;
state.workSocket = LineSocket;
state.EP = epSender;
state.workSocket.BeginReceiveFrom(state.buffer, 0, MessageState.BufferSize,
SocketFlags.None, ref epSender,
new AsyncCallback(ReceiveDataCB),
state);
}
而且,然后在我的回调(ReceiveDataCB),我检索异步对象,然后传递字节的缓冲区给另一个函数进行处理,进而调用上面发布的代码重传到另一端(state.buffer成为readData)。
更新#2:
继我的直觉,我改变了发送代码到下面,除暴安良的SocketAsyncEventArgs和SendToAsync的:
var sendBuffer = new byte[readCount];
Array.Copy(readData, sendBuffer, readCount);
SwitchWindow.LineSocket.BeginSendTo(
sendBuffer, 0, sendBuffer.Length, SocketFlags.None,
p.EP, new AsyncCallback(echoCB), null);
,当然,我说的“ echoCB“回调除了调用EndSendTo之外什么也不做。内存泄漏现在消失了!我怀疑这与创建如此多的SocketAsyncEventArgs对象有关,而异步函数挂在这些对象上,每个数据包一个(每秒33个数据包,可以快速加起来)。我再次查看了SocketAsyncEventArgs的MSDN文档,并注意到在服务器提供的“示例”代码中,他们使用了一组SocketAsyncEventArgs对象。我认为它的设计并不像我使用它的方式一样。我认为整个过程不必为每个调用实例化这些缓冲区等,因此可以重用它们并使服务器获得更好的性能。
看到我的修改我贴 – 2010-07-19 18:32:47