Receiving UDP data fills memory abnormally

I posted some time ago an issue regarding a random crash. Here

After digging through the crash dump, it turned out that this was caused by a stack overflow caused by this :

Timer m_oscReceiverTimer;
IPEndPoint m_endpoint;


void Start()
{
	m_oscReceiverTimer = new Timer();
	m_oscReceiverTimer.Interval = 500d;
	m_oscReceiverTimer.Elapsed += ReceiveTimer;

	m_endpoint = new IPEndPoint(IPAddress.Any, ReceivePort);
	// receiver
	client = new UdpClient(m_endpoint);
	client.JoinMulticastGroup(IPAddress.Parse(ReceiveIP));
	m_oscReceiverTimer.Start();
}

public async Task<OSCPacket> ReceiveOSCPacket()
{
	try
	{
		var result = await this.client.ReceiveAsync();

		if (result == null) return null;
						   
		if (result.Buffer != null && result.Buffer.Length > 0)
		{
		return OSCPacket.Unpack(result.Buffer);
		}
		else
		{
		return null;
		}

	}
	catch (Exception e)
	{
		Console.WriteLine(e.ToString());
		return null;
	}

}



private void ReceiveTimer(object sender, ElapsedEventArgs e)
{

	System.Threading.Tasks.Task.Run(async () =>
	{
		var result = await ReceiveOSCPacket();
	}

}

Short explanation: Every 500ms we are receiving the IPs of devices on the network that broadcast via UDP.

The code seems very simple and yet the memory keeps climbing non stop. I have also tried calling the Garbage Collector after each call thinking it could not keep up the the incoming data but this does not help. I am lost.

Help

Your code is really weird. Why do you use a Timer and call the receive method at a fix interval? You never want to do that on the receiving side. You may call your receive method too fast or too slow. So either packets pile on or you pile on threads that wait for a packet to arrive.

You probably want to call your ReceiveOSCPacket async method in a loop. ReceiveAsync is not a polling method. The returned task will continue once a packet has arrived.

2 Likes