MSMQ BeginPeek/PeekCompleted memory leak
Using Microsoft MessageQueue there seem to be a memory leak related to the PeekCompleted event. I found a related question on experts exchange from 2005, but with no proper answer/solution: http://www.experts-exchange.com/Programming/Misc/Q_213开发者_运维技巧87840.html
Using ANTS Memory Profiler I can see that I get additional pinned instances of Byte[], Int32[], System.Messaging.Interop.MQPROPVARIANTS[], and System.Threading.OverlappedData each time PeekCompleted is triggered.
Reference chain: Byte[] < Object[] < MessagePropertyVariants < Message < AsynchronousRequest < OverlappedData and IOCompletionCallback. The OverlappedData is referenced by GC Roots and System.Threading.Overlapped, and from Overlapped there seems to be a reference back to OverlappedData again, making it a cycle (?).
We are pretty sure we're using MSMQ correctly, and have been experimenting with different stuff, like making sure we dispose the incoming Message object, calling EndPeek explisitly etc, but no luck. No simple code to pinpoint the problem have been produced so far, but is probably my next step. There is obviously the possibility that we are using it wrong, but right now we think there's actually a problem with MSMQ. The leak is small, but over time it adds up.
Does anyone have an idea of how to resolve this memory leak? Similar experiences?
Check that you only call BeginPeek
once. We have also had this problem:
Our problem: we had the same memory leak because of a very small race condition in our code that occasionally resulted in calling BeginReceive
twice. It was hard to track down, and we only really found it by accident when we were comparing performance of a rewrite that fixed the problem with the original code.
Our solution: We added a counter next to each call to BeginReceive and a counter in the Handler for received messages and found that the count was slightly different after 10,000 messages (only by 12) but that has enough to cause 500MB of memory leak (a combination of pinned handles and memory fragmentation).
Why we missed the bug originally: it doesn't seem to happen on .Net v2, but came up when we moved to .Net v4 on 64 bit with multithreading on multi-CPU machine.
精彩评论