I keep a large cache in a dictionary with value IEnumerable<KeyValuePair<DateTime, Double>>
. I remove items from the dictionary periodically and add items to the dictionary periodically. Every now and again I get a System.OutOfMemoryException. I wanted to know why doesn't the garbage collector come to my rescue?
You can do either of the following to address the error: Replace the call to the StringBuilder. StringBuilder(Int32, Int32) constructor with a call any other StringBuilder constructor overload. The maximum capacity of your StringBuilder object will be set to its default value, which is Int32.
OutOfMemoryException Class (System) The exception that is thrown when there is not enough memory to continue the execution of a program.
Remember that a Heap can get fragmented as @Gabe mentioned. Even though you might have free memory it might not have a chunk large enough to allocate the dictionary to when it performs it's resize.
Perhaps you could use the caching block from the patterns and practices library MSDN Library Link that will assist you in implementing a good cache. Maybe you could choose an algorithm that doesn't dynamically allocate memory, with a fixed number of entries?
Also note that if there isn't any memory that you can use then it's a problem with the size of your cache, not the garbage collector.
It's quite possible that the GC is coming to your rescue for a lot of the time, but that you're just going beyond its capabilities sometimes.
Just to be absolutely clear, is this a Dictionary<DateTime, Double>
or a Dictionary<SomeKeyType, IEnumerable<KeyValuePair<DateTime, Double>>>
? If it's the latter, then perhaps you're holding onto references somewhere else?
How large is your cache getting? Do you have monitoring to keep track of it? What makes you think it's the dictionary which is causing the problem? If you have control over how much you cache, have you tried reducing the size?
Since you're asking why the GC doesn't rescue you I'll give an answer to that.
Using a programming language/environment with a garbage collector makes live easier for you but won't make memory management a thing of the past.
If you assign big chunk of memory going over about 2 gig in a 32bit xp machine you're just reached one of the first .Net memory boundaries. Keeping 2 gig in memory is always a bad idea.
On a memory constrained machine running a huge database or the like you'll quickly hit the boundaries of available memory. Since the GC is not OS aware it might nog notice a low memory situation in time (creating huge objects like bitmaps can trigger this situation). Manually calling GC.Collect once you're set a huge object to nothing help a lot here.
Keeping a big dictionary in memory is a very simple description. Can you tell us whats in the collection and how big those items are theoretically.
If you mean big like 2,147,483,647 items you could have hit the Integer size limit.
To sum up:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With