在上一篇 ”拥抱.NET Core系列:MemoryCache 缓存过期” 中我们详细的了解了缓存过期相关的内容,今天我们来介绍一下 MSCache 中的 Options,由此来介绍一些 MSCache 中的内部机制。

MSCache项目

MSCache 目前最新的正式版是 2.0.0,预览版是2.1.0,会与 .NETCore 2.1 一起发布。本篇用了2.0.0版本

开源在 GitHub 上,仓库地址是:https://github.com/aspnet/Caching

NuGet地址为:https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/2.0.0

MemoryCacheOptions

Clock 顾名思义,是用来提供时间的一个成员,缓存里面大量用到了时间来判断缓存是否过期。

CompactOnMemoryPressure 已经被废弃,可以不用管

ExpirationScanFrequency 过期扫描频率(默认为1分钟,可以理解为每过多久移除一次过期的缓存项)

SizeLimit 缓存大小限制(这属于一个说明性属性,而且单位也不是缓存数目,而是缓存真正占用的空间大小)

CompactionPercentage 压缩率(默认0.05,百分比)

Clock

初次见到的时候以为是用来自定义 LocalTime,其实不是(当然要这么做也可以),在 MSCache 中只允许用 Utc 时间,但是为什么既然都是 Utc 时间还要留这个扩展选项呢?

很简单,默认的当前时间是当前系统的当前时间,在一些对时间精度要求比较高的情况下就可以重写 Clock 来实现自己自定义的获取当前时间的逻辑。

ExpirationScanFrequency

缓存无非是一个字典表,当一些缓存项过期失效时候我们需要移除字典表里面的内容。

然而准确的做到每个缓冲项过期就进行移除是非常损失性能的(类似GC),所以 MSCache 提供了一个属性来设置,没间隔多久才进行一次过期缓存移除。

这个值默认为1分钟。

什么时候会进行过期缓存清理?

  1. 添加新的
  2. 获取缓存项
  3. 删除缓存项目
  4. 当有缓存项过期(通过过期回调)

这边就解释了上一节的最后为什么没有回调输出。

因为MSCache里面没有使用定时器来进行过期扫描。

ps:缓存过期清理是一个异步方法也就是不会堵塞当前线程。

SizeLimit

这个属性在 MemoryCache 中几乎没有用,在 MemoryCache 中关于缓存项的大小默认都是null或0。

因为这个属性并不是缓存项的数量,而是缓存真正占用的空间大小,如这个缓存项占用了多少内存。

然而在.NET中计算一个对象所占用的内存是很难且损耗性能的,所以在 MemoryCache 中这个属性几乎可以看做没有。

当然你可以通过手动设置缓存项的Size来启用相关功能。这边我们只简单说明,详细讲解会在后面的分布式缓存中进行说明。

这个属性的作用是:当所有缓存大小超过这个值的时候进行一次缓存压缩。

CompactionPercentage

当内存大小超过 SizeLimit 时候进行压缩的比率,默认值是0.05,也就是百分之5。

具体的计算方式是

得到剩余的缓存大小 SizeLimit * 1 – CompactionPercentage

得到需要压缩的大小 CurrentSize  –  (SizeLimit * 1 – CompactionPercentage)

缓存的清理优先级

这时候就牵扯到 CacheEntry 中的 Priority 属性了,当发生这种情况的时候 MSCache 会按以下优先级进行压缩处理

  1. Low
  2. Normal
  3. High

为什么没有  NeverRemove ?因为 NeverRemove 永远不会在超过 SizeLimt 时候进行清理。

那么当缓存大小超过SizeLimit时,MSCache会

先清理Low优先级的缓存项(不管是否过期)

再清理Normal优先级的缓存项(不管是否过期)

继续清理High优先级的缓存项(不管是否过期)

CacheEntry 默认的 优先级为:Normal。

写在最后

今天介绍了一些 MSCache 的内部机制,后续会讲一下 缓存域 和 一些小技巧。

.NET技术栈QQ群:384413261(点击加入 .NET Group

拥抱.NET Core系列:MemoryCache 缓存选项的更多相关文章

  1. 拥抱.NET Core系列:MemoryCache 缓存选项 (转载)

    阅读目录 MSCache项目 MemoryCacheOptions ExpirationScanFrequency SizeLimit CompactionPercentage 写在最后 在上一篇 ” ...

  2. 拥抱.NET Core系列:MemoryCache 缓存域

    在上一篇“<拥抱.NET Core系列:MemoryCache 缓存选项>”我们介绍了一些 MSCache 的机制,今天我们来介绍一下 MSCache 中的缓存域. MSCache项目 M ...

  3. 拥抱.NET Core系列:MemoryCache 缓存域(转载)

    阅读目录 MSCache项目 缓存域 写在最后 在上一篇“<拥抱.NET Core系列:MemoryCache 缓存选项>”我们介绍了一些 MSCache 的机制,今天我们来介绍一下 MS ...

  4. 拥抱.NET Core系列:MemoryCache 缓存过期

    在上一篇"拥抱.NET Core系列:MemoryCache 初识"中我们基本了解了缓存的添加.删除.获取,那么今天我们来看看缓存的过期机制.这里和上篇一样将把"Micr ...

  5. 拥抱.NET Core系列:MemoryCache 缓存过期 (转载)

    阅读目录 MSCache项目 MSCache提供的过期方式 绝对时间到期 滑动时间到期 自定义过期策略 过期策略组合拳 缓存过期回调 写在最后 在上一篇”拥抱.NET Core系列:MemoryCac ...

  6. 拥抱.NET Core系列:依赖注入(2)

    上一篇"拥抱.NET Core系列:依赖注入(1)"大体介绍了服务注册.获取和生命周期,这一篇来做一些补充. 由于内容跨度大(.NET Core.ASP.NET Core),所以文 ...

  7. 拥抱.NET Core系列:MemoryCache 初识

    Cache是一个绝大多数项目会用到的一个技术,说起到缓存可能就联想到 Set.Add.Get.Remove.Clear 这几个方法.那么在.NET Core中微软给我们带来了什么样的缓存体验呢?今天我 ...

  8. 拥抱.NET Core系列:MemoryCache 初识 (转载)

    阅读目录 MSCache能做什么? 从IMemoryCache说起 开发者的体验 写在最后 Cache是一个绝大多数项目会用到的一个技术,说起到缓存可能就联想到 Set.Add.Get.Remove. ...

  9. 拥抱.NET Core系列:依赖注入(1)

    依赖注入时编程手段中解耦和封装的一个非常重要的手段,我本人已经到了没有DI无法编写项目的程度了,在.NET Framework中微软并没有在FCL中引入DI,虽然推出了"Unity" ...

随机推荐

  1. 监督学习:随机梯度下降算法(sgd)和批梯度下降算法(bgd)

    线性回归 首先要明白什么是回归.回归的目的是通过几个已知数据来预测另一个数值型数据的目标值. 假设特征和结果满足线性关系,即满足一个计算公式h(x),这个公式的自变量就是已知的数据x,函数值h(x)就 ...

  2. 用Android属性动画实现和演示迪士尼动画基本原则

    本文将介绍在Android平台上实现和演示迪士尼动画基本准则. 项目开源,GitHub: https://github.com/vhow/animation 说明: 演示动画原则的想法源自 Anima ...

  3. redis 设置认证密码

    通过修改redis配置文件(redis.conf)修改验证密码.(重启生效) requirepass myRedis 客户端通过密码登录redis并进行操作 redis-cli -h 127.0.0. ...

  4. 在OS X系统中php访问sftp时需要ssh2扩展的安装

    php -v brew install homebrew/php/php55-ssh2 [实现方式] <?php $connection = ssh2_connect('192.168.0.14 ...

  5. 学习python3函数笔记

    Python内置了很多有用的函数,我们可以直接调用. 要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数.可以直接从Python的官方网站查看文档: http://doc ...

  6. WebView性能优化--独立进程

    Android允许一个app同时存在多个进程,可以根据需要把不同的模块放到不同进程中处理. 一.WebView独立进程的好处 1.有效增大App的运存,减少由webview引起的内存泄露对主进程内存的 ...

  7. C语言_指针和数组的几种访问形式

    敲几行代码来看看几种访问的形式~ #include <stdio.h>;int main() { ] = {, , , , , }; //初始化5个元素的一维数组 int *p = arr ...

  8. Ceph神坑系列

    1. 在使用librbd的过程中,发现一个如果ceph集群异常librbd函数不返回的问题,对librbd的源码进行跟踪,发现了rados接口中的rados_mon_op_timeout(how ma ...

  9. 生成1~n的排列

    直接递归打印. 代码如下 #include<cstdio> void dfs(int *a,int cur,int n) { if(cur==n) { for(int i=0;i<n ...

  10. CodeForces-748B

    关键在于判断是否能够得到解决办法,我的思路就是用一个数组来记录每个小写字母对应的按键,如果它出现对应两个级以上不同的按键那么就说明不能得出解决办法,直接打印'-1'.如果能够得出解决办法,就扫描一下数 ...