在上一篇 ”拥抱.NET Core系列:MemoryCache 缓存过时” 中咱们详细的了解了缓存过时相关的内容,今天咱们来介绍一下 MSCache 中的 Options,由此来介绍一些 MSCache 中的内部机制。html
MSCache 目前最新的正式版是 2.0.0,预览版是2.1.0,会与 .NETCore 2.1 一块儿发布。本篇用了2.0.0版本git
开源在 GitHub 上,仓库地址是:https://github.com/aspnet/Cachinggithub
NuGet地址为:https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/2.0.0缓存
Clock 顾名思义,是用来提供时间的一个成员,缓存里面大量用到了时间来判断缓存是否过时。异步
CompactOnMemoryPressure 已经被废弃,能够不用管分布式
ExpirationScanFrequency 过时扫描频率(默认为1分钟,能够理解为每过多久移除一次过时的缓存项)性能
SizeLimit 缓存大小限制(这属于一个说明性属性,并且单位也不是缓存数目,而是缓存真正占用的空间大小)线程
CompactionPercentage 压缩率(默认0.05,百分比)3d
初次见到的时候觉得是用来自定义 LocalTime,其实不是(固然要这么作也能够),在 MSCache 中只容许用 Utc 时间,可是为何既然都是 Utc 时间还要留这个扩展选项呢?orm
很简单,默认的当前时间是当前系统的当前时间,在一些对时间精度要求比较高的状况下就能够重写 Clock 来实现本身自定义的获取当前时间的逻辑。
缓存无非是一个字典表,当一些缓存项过时失效时候咱们须要移除字典表里面的内容。
然而准确的作到每一个缓冲项过时就进行移除是很是损失性能的(相似GC),因此 MSCache 提供了一个属性来设置,没间隔多久才进行一次过时缓存移除。
这个值默认为1分钟。
这边就解释了上一节的最后为何没有回调输出。
由于MSCache里面没有使用定时器来进行过时扫描。
ps:缓存过时清理是一个异步方法也就是不会堵塞当前线程。
这个属性在 MemoryCache 中几乎没有用,在 MemoryCache 中关于缓存项的大小默认都是null或0。
由于这个属性并非缓存项的数量,而是缓存真正占用的空间大小,如这个缓存项占用了多少内存。
然而在.NET中计算一个对象所占用的内存是很难且损耗性能的,因此在 MemoryCache 中这个属性几乎能够看作没有。
固然你能够经过手动设置缓存项的Size来启用相关功能。这边咱们只简单说明,详细讲解会在后面的分布式缓存中进行说明。
这个属性的做用是:当全部缓存大小超过这个值的时候进行一次缓存压缩。
当内存大小超过 SizeLimit 时候进行压缩的比率,默认值是0.05,也就是百分之5。
具体的计算方式是
获得剩余的缓存大小 SizeLimit * 1 – CompactionPercentage
获得须要压缩的大小 CurrentSize – (SizeLimit * 1 – CompactionPercentage)
这时候就牵扯到 CacheEntry 中的 Priority 属性了,当发生这种状况的时候 MSCache 会按如下优先级进行压缩处理
为何没有 NeverRemove ?由于 NeverRemove 永远不会在超过 SizeLimt 时候进行清理。
那么当缓存大小超过SizeLimit时,MSCache会
先清理Low优先级的缓存项(无论是否过时)
再清理Normal优先级的缓存项(无论是否过时)
继续清理High优先级的缓存项(无论是否过时)
CacheEntry 默认的 优先级为:Normal。
今天介绍了一些 MSCache 的内部机制,后续会讲一下 缓存域 和 一些小技巧。
.NET技术栈QQ群:384413261(点击加入 .NET Group)