John Fremlin's blog: The .NET CLR and failing to allocate

Posted 2010-04-22 19:44:00 GMT

I've never found a VM that handled running out of memory properly. Maybe Lispworks? I know that Allegro and SBCL can just crash horribly when you try to allocate too much. And Java tends to bring down my machine. I was a .NET evangelist to the all the Scala people I ran into, but now having used it, I have to eat my words.

Take a look at this C# (pseudo-code as I haven't .NET at home).

var sb = new StringBuilder();
while(true){
    try {
        sb.EnsureCapacity(1000000);
        break;
    }catch(OutOfMemoryException){
        GC.Collect();
    }
}

Even when there is plenty of memory free (2GB available on the machine and only 300MB in the program), if you rapidly repeatedly allocate this 20MB, sometimes it will throw an OutOfMemoryException. This would normally crash your program but you can just call GC.Collect() to get the GC to agree to allocate more heap for the program. It is insane that it throws OutOfMemoryException when there is so, so much space free to allocate! The fragmentation argument does not wash, as the program could freely allocate more memory. And simply, why doesn't the allocator call GC.Collect instead of throwing this exception? Having managed code in a VM means that you can de-fragment your memory when you feel like it . . .

PS. And while ThreadPool.QueueUserWorkItem is pretty great, parallel for, isn't.

Post a comment