I was recently faced with the task of trying to figure out why, sporadically, when Calling an MSMQ's Peek() function, an application would loose memory for no apparent reason. It was pretty weird and hard to even recreate.
If you try to peek or receive messages on a remote queue which does not exist (the queue or the machine) you will loose memory for every try you do. The bad part is that there is no direct way to check if a remote queue exists, but there is a workaround.
MessageQueue.Exists(queuename) only works for local queues. If you try to send a message to a queue using this format name “FormatName:direct=os:<machinename>\private$\myqueue” you will not get an error if the queue does not exists. If you try to peek or receive you get an error, but at that point the memory is already lost.
Sample code to reproduce memory leak:
MessageQueue mq = new MessageQueue("FormatName:direct=OS:dcc-roger-test\\private$\\1234"); System.Messaging.Message msg = new System.Messaging.Message();
Forcing a GC.Collect / GC.WaitForPendingFinalizers / GC.GetTotalMemory(true) gives back a small portion of the lost memory. Be aware of the virtual memory usage of your .net applications, in my example I had about 15mb in “mem usage” in Task Manager and over 1 gb in virtual memory usage.
The workaround is simple, just make sure you can read from the queue before you try to peek / receive from it. CanRead returns false if the queue does not exist or if you do not have rights to access it.