Caching Application Block Overhead?

Topics: Caching Application Block
Jun 28, 2007 at 6:12 AM
The caching application block appears to consume a lot a of memory. I created a simple console application that stored 1000 integers in a Dictionary<Int32, Int32> object. At runtime this console application consumed 4,462 K of memory. I then created a second console application using the caching application block to store the integer values instead of the Dictionary and this application consumed 12,652 K of memory. I then ran these two application again storing 1,000,000 integer values and the memory consumed was 4,968 K and 142,728 K respectively. 142 MB of memory to cache 1 million integer values seems extreme. Is this amount of overhead normal or am I doing something wrong?
Jun 28, 2007 at 1:23 PM

It's true the values look unusual. What's the value for "maximumElementsInCacheBeforeScavenging" in the configuration file? There is a thread discussing an issue that might explain this behavior at Please try raising this value to 1 million in your second run and compare the memory footprint.

Jun 28, 2007 at 8:50 PM

Thanks for the reply.

In both case I set the "maximumElementsInCacheBeforeScavenging" to 1000 for the first run and 1 million for the second run so I don't believe this is the issue.

I will definitely take a look the the other thread you offered.


Jul 4, 2007 at 7:14 PM
Hi Scott,

I did some profiling on a repro that should be similar to yours, adding also a test for a HashTable because that's the underlying collection used by the cache. I just looked at the total allocations, and didn't care for the lifetime of the objects or any possible leak. The total allocation numbers for the caching block, the hash table and the dictionary were 240, 76 and 51 megabytes respectively.

Comparing the footprint of the caching block with a Dictionary<int, int> is not fair really. Using the cache requires creating a string key (I used Convert.ToString(i)) and the values are boxed; the amount of memory for these objects was 40 megs for both cache and hashtable (over 50% of the allocated memory in the hash table case).

When comparing the cache and the hashtable, I got about 100 megs of pure caching block overhead (CacheItems and expiration arrays); that's about 100 bytes per item in the cache. While it's certainly larger than the memory used by the items themselves, it doesn't seem to be it is a realistic comparison. If anything, it shows the cache overhead (which supports the block's features such as expirations, priorities, custom refresh actions, etc) may be overkill for storing very small objects but if objects are small you probably don't need a cache and can keep them all in memory.

The only weird numbers I got were an extra 25 megs used by hashtable internal objects and a whooping 42 megs gone in integers. The hashtable bits were allocated when cloning the internal hash table before doing an expiration sweep; there could be some room for improvement there. For the ints, I traced them back to the calls to DateTime.Now issued when adding an element. It's certainly very expensive, and there might be room for improvement there (probably by using DateTime.UtcNow instead). Both would require careful changes in the implementation, and this overhead should remain constant as the size of the cached elements increase, making it less significant.

The purpose of this analysis is to provide information about the nature of the overhead you should expect when using the block; whether it is acceptable or not will depend on a specific scenario.

Hope this helps,
Jul 5, 2007 at 8:04 PM

Thank you for taking the time to compare the HashTable and Caching Application Block. You've provide some great information and in my case I definitely do think the overhead is worth the memory foot print.

Thanks again,