У меня есть простое Windows-приложение .net 3.5sp1 (на C #), которое работает как UDP-сервер.Он прослушивает порт, получает данные от конечной точки, а затем повторно передает то, что он получает, другой конечной точке (т. Е. Ретрансляции для потока данных прямого вещания).Что я испытываю, так это то, что после того, как соединение установлено примерно на 20 минут, оно начинает ухудшаться.Кроме того, я заметил, что он поглощает около 50-100 КБ памяти в секунду, которая никогда не выпускается после GC.Я должен закрыть приложение и перезапустить его.Нехорошо.Я сузил проблему до следующего кода, который выполняет повторную передачу на другую сторону:
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?
ОБНОВЛЕНИЕ:
Я создаю экземпляр объекта состояния (выполняется только один раз) при инициализации сокета.У объекта состояния есть свойство, называемое «буфер», которое является байтовым массивом.Я получаю асинхронные данные из сокета следующим образом:
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) я получаю асинхронный объект, а затем передаю байтовый буфер другой функции для обработки, которая вturn вызывает код, указанный выше, для повторной передачи на другую сторону (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 пакетах в секунду, которые могут быстро складываться).Я еще раз просмотрел документацию MSDN для SocketAsyncEventArgs и заметил, что на предоставленном «примере» кода сервера они использовали пул объектов SocketAsyncEventArgs.Я не думаю, что он действительно разработан, чтобы работать так, как я его использовал.Я думаю, что весь смысл состоит в том, что не нужно создавать экземпляры этих буферов и т. Д. Для каждого вызова, поэтому их повторное использование и повышение производительности сервера.