lysergic-acid
lysergic-acid

Reputation: 20050

OutOfMemoryException on a particular machine when running tests

We have a test of NUnit tests that are suffering OutOfMemoryExceptions on a particular machine.

After investigation it seems that it is not a memory issue, but a Handle issue (we are allocating too many Bitmap objects and not releasing them).

The issue is, that this runs perfectly on a particular machine, while failing with this error on another one.

  1. Failing machine is a Hyper-V VM with Windows7 x64 (6 GB ram)
  2. Working Machine is a physical machine Windows XP (2 GB ram)

I know that the best solution would be to clean up the code to dispose of any Bitmap objects, but i am interested in knowing why do these 2 machines differ in behavior when executing the same code?

Upvotes: 2

Views: 233

Answers (2)

Hans Passant
Hans Passant

Reputation: 941447

That's unlikely, Windows allows you to leak 10,000 handles before it gets cranky about the way your program behaves and refuses to let you allocate more. By then you've consumed massive amounts of virtual memory space for the pixel data in the bitmaps. Stored in unmanaged memory, the garbage collector is unaware of it. VM space that doesn't get released unless you call Dispose() or the garbage collector takes care of it by running the finalizer.

The GC doesn't typically get the job done, the Bitmap class is a very small object, not big enough to trigger a GC by itself. You'd have to allocate about 60,000 of them to trigger a GC. You'll never get there, you'll run out of VM space first unless the bitmaps are very small, handles next. Calling Dispose() is optional, but that stops being optional for bitmaps since the finalizer just can't get the job done in time.

The amount of RAM plays no role in this whatsoever, a .NET program always bombs on it not being able to find a hole in the VM address space that's big enough to fit the requested size. Also an issue with bitmaps, they tend to need big holes. It just takes a DLL that gets loaded at an awkward base address to cut a nice big hole into two. Otherwise a problem that's easily solved, just set the target platform of the program to AnyCPU. A test program has a configuration value for that. Works on that Win7 machine. But of course, that's not a valid reason to skip the Dispose() calls.

Upvotes: 1

jlew
jlew

Reputation: 10591

Read this: http://blogs.technet.com/b/markrussinovich/archive/2010/02/24/3315174.aspx

You will find a table of the differences between various versions of Windows with respect to GDI heap. Short answer: XP = 3Mb limit, Win7R2x64 = 20Mb limit. Free RAM doesn't matter, these are hard limits.

Upvotes: 1

Related Questions