I’ve been tracking massive memory leeking in my application and it seems the issue is the MemoryStream class. Whenever I use one, either with the ‘using’ key word or explicit close/dispose, the memory will never be collected by the garbage collector. What is wrong here?
byte[] bData = System.IO.File.ReadAllBytes( "F:\\application_exit_bw.png" );
using( System.IO.MemoryStream hMemoryStreamOutput = new System.IO.MemoryStream())
{
for ( int i = 0; i < 10000; i++ ) hMemoryStreamOutput.Write( bData, 0, bData.Length );
}
Thread.Sleep(Timeout.Infinite);
With explicit close/dipose the behaviour stays the same. Memory is occupied and will stay that way until I close my application, or, the application filled all of the system memory. Help?
Another side of the problem is what you are using to determine “memory leak”. There are many different ways to measure “free’ memory and depending on it you may get tottaly different results.
There is one more thing with MemoryStream (and any other large 86K+) allocations – they use Large Objects Heap that will be only collected on full GC, to trigger it you may need to run GC.Collect twice. In normal flow of an application it will happen rare enough, so you may not see this memory freed before application shutdown. To diagnose – check GC collection performance counter (number of GC).
And one more: if you are trying to solve memory leak because you are getting “out of memory” exception it may be caused by address space fragmentation (normally only for 32-bit processes). If it is the case – consider creating your own memory stream that does not allocate memory in single chunk and then have to copy it when growing the stream. Or at least try to preallocate space in the stream.