我有一个客户端应用程序,通过UDP或TCP套接字从服务器接收视频流。
最初,当使用.NET 2.0编写代码时,代码使用的是BeginReceive / EndReceive和IAsyncResult。 客户端在其自己的窗口中显示每个视频,并使用它自己的线程与服务器通信。 但是,由于客户端应该长时间运行,并且可能同时存在64个视频流,因此每次调用数据接收回调时都会分配IAsyncResult对象的“内存泄漏”。
这会导致应用程序最终耗尽内存,因为GC无法及时处理块的释放。我使用VS 2010性能分析器验证了这一点。
所以我修改了代码以使用SocketAsyncEventArgs和ReceiveFromAsync(UDP case)。 但是,我仍然看到内存块的增长:
System.Net.Sockets.Socket.ReceiveFromAsync(class System.Net.Sockets.SocketAsyncEventArgs)
我已经阅读了有关实现代码的所有示例和帖子,但仍然没有解决方案。
以下是我的代码的样子:
// class data members
private byte[] m_Buffer = new byte[UInt16.MaxValue];
private SocketAsyncEventArgs m_ReadEventArgs = null;
private IPEndPoint m_EndPoint; // local endpoint from the caller
初始化:
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_Socket.Bind(m_EndPoint);
m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, MAX_SOCKET_RECV_BUFFER);
//
// initalize the socket event args structure.
//
m_ReadEventArgs = new SocketAsyncEventArgs();
m_ReadEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(readEventArgs_Completed);
m_ReadEventArgs.SetBuffer(m_Buffer, 0, m_Buffer.Length);
m_ReadEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
m_ReadEventArgs.AcceptSocket = m_Socket;
开始阅读流程:
bool waitForEvent = m_Socket.ReceiveFromAsync(m_ReadEventArgs);
if (!waitForEvent)
{
readEventArgs_Completed(this, m_ReadEventArgs);
}
阅读完成处理程序:
private void readEventArgs_Completed(object sender, SocketAsyncEventArgs e)
{
if (e.BytesTransferred == 0 || e.SocketError != SocketError.Success)
{
//
// we got error on the socket or connection was closed
//
Close();
return;
}
try
{
// try to process a new video frame if enough data was read
base.ProcessPacket(m_Buffer, e.Offset, e.BytesTransferred);
}
catch (Exception ex)
{
// log and error
}
bool willRaiseEvent = m_Socket.ReceiveFromAsync(e);
if (!willRaiseEvent)
{
readEventArgs_Completed(this, e);
}
}
基本上代码工作正常,我看到视频流完美,但这种泄漏真的很痛苦。
我错过了什么吗?
非常感谢!!!
答案 0 :(得分:0)
而不是在readEventArgs_Completed
使用!willRaiseEvent
后返回到方法顶部后递归调用goto
。当我的模式与你的模式类似时,我注意到我正在慢慢地咀嚼堆栈空间。