2

I'm trying to use .NET System.Runtime.Caching.MemoryCache (.NET Framework 4.7.2). I'm creating my own instance and set memory limit by using CacheMemoryLimitMegabytes parameter.

I use quite short keys - about 50 characters in average. Cached data is just long values (DB record IDs).

I use CacheItemPolicy with SlidingExpiration set to 15 minutes and RemovedCallback set to my method so I can log items evictions.

In my unit tests everything works fine. I set cache memory limit to 1 MB (just for testing) and I'm able to store thousands of items before eviction starts.

But when I try to use MemoryCache in application on dev server and set memory cache limit to 1 MB cache, I experience eviction after adding approximately 10 items to cache.

I tried to measure memory used by cache by approach described here:

In unit test, it reports reasonable values, but when I used my solution with memory cache on dev server, I get approx. 4.5 MB just after adding single item to cache. I even tried to call GC.Collect(2, GCCollectionMode.Forced) before checking ApproximateSize of _sizedRefMultiple, but still getting this value.

And because eviction relies on values returned from ApproximateSize as well, cache starts evicting items almost immediately. So I suspect that issue is caused by value reported by ApproximateSize.

Has anyone experienced similar behaviour? Do you have any tips what to check?

micina
  • 21
  • 1
  • 1
    On dev server you get 4.5mb for a single item. does it increases ~4mb in size for each new item or it initially reserves 4.5mb ? – RezaNoei Feb 20 '23 at 05:42
  • @RezaNoei When I just create new instance of MemoryCache without adding items to it and check ApproximateSize, it reports about 120 kB (on both my machine and dev server). But when I add first item to cache, ApproximateSize reports ~4.5 MB on dev server while only less than 100 kB on my machine. Subsequent adding of items doesn't increase value reported by ApproximateSize so much, only about 2 to 10 kB. Between calls to ApproximateSize I have to call GC.Collect() otherwise size is not updated (see https://stackoverflow.com/questions/31889287/what-exactly-do-memorycaches-memory-limits-mean). – micina Feb 24 '23 at 07:05
  • There might be a little difference in the implementation maybe for release build (initial memory reservation). I don't count on Microsoft guys as error free developers. In your situation I will try to collect my observations on high stress environment. I will suspicious on the possible Memory-leakage. If there were any sign of Memory-leakage I will switch to some third parties like Redis or I will implement my own. As `.Net` is not an open-source product, finding the reason is a time consuming task. In similar cases on `.NetCore` you are able to read the code and find the cause more easier. – RezaNoei Feb 27 '23 at 11:59

0 Answers0