.NET的MemoryCache是C#对象的缓存。有些对象可能具有复杂的结构,而其他对象可能具有不安全的引用。对于实现PhysicalMemoryLimit,C#是否使用某些魔法,还是只计算每个对象的浅层大小?
我怀疑后者是正确的。但是,如果我将同一个对象多次放入缓存中(例如跟踪丢失的项),那么该大小会被计算一次,还是对包含该实例的每个条目都会计算一次?
.NET的MemoryCache是C#对象的缓存。有些对象可能具有复杂的结构,而其他对象可能具有不安全的引用。对于实现PhysicalMemoryLimit,C#是否使用某些魔法,还是只计算每个对象的浅层大小?
我怀疑后者是正确的。但是,如果我将同一个对象多次放入缓存中(例如跟踪丢失的项),那么该大小会被计算一次,还是对包含该实例的每个条目都会计算一次?
.NET MemoryCache类似于ASP.NET缓存类。如果我们查看ASP.NET缓存,我们会看到一个名为CacheItemRemovedCallback的函数。当从缓存中删除一个项目时,就会触发此函数。
此函数使用回调函数给出CacheItemRemovedReason。如果我们查看原因,我们会发现,系统可以通过释放内存来从缓存中删除一个项目。因此,虽然PhysicalMemoryLimit给出了单个线程可以使用的物理内存百分比,但我认为如果达到限制,它们会让系统清除缓存。
如果您使用Add函数将Cache项目放到缓存中,它将作为新的CacheItem实例添加,因此会被多次计算。如果您使用AddOrGetExisting函数,它将检查该项是否已经在缓存中。如果是,则使用该实例而不是新实例。因此,它只会被计算一次。new Microsoft.VisualBasic.Devices.ComputerInfo().AvailablePhysicalMemory
获取此信息。因此,缓存应该会做两件事:
if (UnsafeNativeMethods.GlobalMemoryStatusEx(ref memoryStatusEx) != 0) { s_totalPhysical = memoryStatusEx.ullTotalPhys; s_totalVirtual = memoryStatusEx.ullTotalVirtual; }
这在计算压力时被使用:
if (memory >= 0x100000000) { _pressureHigh = 99; } else if (memory >= 0x80000000) { _pressureHigh = 98; }
也许我没有理解你的意思,但是源代码中有很多答案。 - Sergey.quixoticaxis.Ivanov您无法轻松设置MemoryCache类的PhysicalMemoryLimit或CacheMemoryLimit成员,因为它们没有实现setter方法(至少在.Net 4.0版本中)。
我同意其他答案中提到的,如果您只想缓存一个对象的单个实例,则应使用AddOrGetExisting。如果不是,则可以使用不同的键缓存备用项。