Windows 7 x64 running a x86 .NET app will throw Out of memory unless I do GC.Collect
I have found the solution but the behavior is quite worrying and thought I ask here if anyone else seen it too.
Basically, the same binary which has been pinned to be built in x86 (will explain why below) running in x64 Windows 7 will leak unless I force a GC.Collect()
To explain:
- The application does a lot of bitmap rendering (>60 per/sec)
- There is an external C++ dll (managed C++)
- There are two threads (worker and ui)
- There is UI refreshing (stats)
- This behavior happens only on this machine, Windows 7 x86 runs it fine.
The application will grow to over 1.5G and eventually throw an Out Of Memory exception. The faster (1) works the faster the exception.
For those ready to shoot (2) for causing the leak, I did test removing it and the leak remained plus the memory gets released fine if 开发者_StackOverflow社区I do GC.Collect(), which in my books is a .NET issue.
Thank you.
OK, for what is worth, here is my catch.
I have seen exactly the same issue you are experiencing. It was back in .NET 2.0 but I was working with big images and although I would dispose the images, the memory consumption would go up - until I manually call GC.Collect()
.
What else was similar? Hosting! My application was an unmanaged EXE and that would use COM
to create a an object which was a .NET class exposed to COM
. This would cause the unmanaged EXE to host the CLR.
On Windows X64, X32 apps will be loaded in WOW (windows on windows) mode which is a similar hosting which I believe can exhibit similar issues. It seems GC
cannot fully understand the memory consumption when it is in a hosted environment.
Are you properly disposing your bitmaps - and all other disposable resources including GDI+ objects?
using(Bitmap bitmap = ...)
{
... do your stuff
}
You need to look at your application to find the problem - clearly 1.5GB is excessive for a 32-bit app. The fact that you are getting different behaviour on different machines with different OS doesn't mean you should blame the OS.
You could try not to rely on the garbage collector as much. If you rewrite your draw code to clean up unused resources, you probably won't run into the scenario described.
Image.Dispose()
Note Always call Dispose before you release your last reference to the Image. Otherwise, the resources it is using will not be freed until the garbage collector calls the Image object's Finalize method.
You have to .Dispose() of your bitmaps when you stop using them. The GC will eventually collect this memory (when it runs the finalizer) even if you don't explicitly call .Dispose() - but the GC is not a magic cure for over-allocating memory, if you do it faster then the GC can collect them, using resources the GC cant control directly (unmanaged resources are exactly that) - then the GC mechanism can't help you.
By calling GC.Collect(0) you are forcing the GC to process the object tree and call all the finalizers, if you don't call it then the GC runs when it thinks it's time, and by then it's too late (due to the high allocation rate).
精彩评论