缓存 - 运行时内存缓存

Posted Kuningasic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存 - 运行时内存缓存相关的知识,希望对你有一定的参考价值。

 

    平时开发程序时,中大型项目都是使用Redis缓存,但在一些较小的项目中,则使用运行时缓存,由.NET FRAMEWORK 提供,命名空间System.Runtime.Caching。

    在下基础不太好,对缓存这块从未深究,只认为可以达到预想中的目标就够了,所以平时基本都是逐渐摸索。

    近来,开发一个交警内部使用的管理系统,要求减少读取数据库,并且每个用户的数据必须是隔离的。这需要用到缓存。使用过程中有个疑问,运行时缓存是将对象拷贝一份保存起来,还是修改对象的内存策略。

   

    平时比较忙,今天恰好有点时间,写了一个测试来验证我的猜想,从来没人说过或是哪里讲过这块知识,现在分享给其他可能同样有疑问的同学。

 

先贴下我写的测试类,如果有哪个地方会导致结果不太准确,请指出:

// 用于缓存的类
        public class CacheEntity
        {
            public Guid Guid { get; set; }
            public int State { get; set; }
            public DateTime CachedOn { get; set; }
            public string Desc { get; set; }

            public override string ToString()
            {
                return $"Object[{this.Guid}] State: [{State}] CachedOn:[{CachedOn}] Desc:[{Desc}].";
            }
        }

 

// 获得即将缓存的对象
       protected virtual CacheEntity GetTestCacheEntity()
        {
            return new CacheEntity
            {
                Guid =  Guid.NewGuid(),
                CachedOn = DateTime.Now,
                Desc = "初始化",
                State = 1
            };
        }
       
       // 获得测试使用的缓存策略
        protected virtual ICacheManager GetTestCacheManager()
        {
            return new MemoryCacheManager();
        }

 

接下来就是测试方法。

/// <summary>
        /// 验证猜想, 缓存数据, 是重新定义对象在内存中的保存策略.
        /// 并不是拷贝一份副本进行缓存, 而是将内存中的对象延迟销毁.
        /// </summary>
        [Test]
        public void Valid_mind()
        {
            var originalEntity = GetTestCacheEntity();

            var cacheManager = GetTestCacheManager();

            var cacheKey = "CacheEntity";
            cacheManager.Set(cacheKey, originalEntity, 5);

            cacheManager.IsSet(cacheKey).ShouldBeTrue();

            Console.WriteLine($"{DateTime.Now}: Get cache...");
            var cacheEntity = cacheManager.Get<CacheEntity>(cacheKey);
            cacheEntity.Guid.ShouldEqual(originalEntity.Guid);
            cacheEntity.State.ShouldEqual(originalEntity.State);
            cacheEntity.CachedOn.ShouldEqual(originalEntity.CachedOn);
            cacheEntity.Desc.ShouldEqual(originalEntity.Desc);
            Console.WriteLine(cacheEntity);
            Console.WriteLine($"{DateTime.Now}: Entity has been cache.");

            Console.WriteLine();
            Console.WriteLine($"-------------------------------------");
            Console.WriteLine();
            Console.WriteLine($"{DateTime.Now}: Change Entity\'s data, and valid again.");
            cacheEntity.Guid = Guid.NewGuid();
            cacheEntity.State = 2;
            cacheEntity.CachedOn = DateTime.Now;
            cacheEntity.Desc = "数据已更改";

            Console.WriteLine($"{DateTime.Now}: Get cache again...");
            cacheEntity = cacheManager.Get<CacheEntity>(cacheKey);
            Console.WriteLine(cacheEntity);
            Console.WriteLine($"{DateTime.Now}: Test ends.");
        }

在测试方法中,仅设置一次缓存,其他都是读取该缓存。

下面是测试结果:

image

结论是:

    运行时缓存更改了对象的内存存储策略,这使得对象不被GC回收,在接下来的过程中可以再次使用。

以上是关于缓存 - 运行时内存缓存的主要内容,如果未能解决你的问题,请参考以下文章

缓存 - 运行时内存缓存

CPU运行时优化(高速缓存指令重排内存屏障等)

CPU运行时优化(高速缓存指令重排内存屏障等)

图片三级缓存

Rails:旧数据与新数据不匹配时如何更新片段缓存

如何缓存片段视图