缓存 - 运行时内存缓存

平时开发程序时,中大型项目都是使用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.");
        }

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

下面是测试结果:

结论是:

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

时间: 2024-08-01 08:32:52

缓存 - 运行时内存缓存的相关文章

Android之本地缓存——LruCache(内存缓存)与DiskLruCache(硬盘缓存)统一框架

本文参考郭霖大神的DiskLruCache解析,感兴趣的朋友可以先到http://blog.csdn.net/guolin_blog/article/details/28863651了解. 一.前言 该框架或者说库,主要是用于本地的图片缓存处理. 数据的存入 当你取到图片的元数据,会将数据存入硬盘缓存以及内存缓存中. 数据的获取 取数据的时候,先从内存缓存中取: 如果没有取到,则从硬盘缓存中取(此时如果硬盘缓存有数据,硬盘缓存会重新将数据写入内存缓存中): 如果硬盘缓存中没有取到,则从网上重新获

Java 进阶(一) JVM运行时内存模型

1.JVM运行时数据区域的划分 a.程序计数器(Program Counter Register) 一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.每个线程拥有独立的一个计数器,如果当前执行的是Native方法,则计数器值为空. b.JVM栈(Java Virtual Machine Stack) 描述Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stacks Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息. 每一个方法从调用直至执行完成

深入理解java虚拟机一 JAVA运行时内存区域与class文件

一 JAVA运行时内存区域 JVM在加载class文件时,会将class文件定义的数据结构转为运行时内存中的数据,那么jvm是如何安排运行时的内存区域呢? jvm将运行时内存划分为以下几个部分: 堆:所有线程共享 方法区:类信息.静态变量.常量等 运行时常量池:class文件的常量池(字面常量和符号引用)+运行时产生的常量 程序计数器:  当前线程执行的字节码的行号指示器 虚拟机栈:栈帧 = 本地局部变量表.操作数栈.动态链接.出口信息 本地方法栈:native方法 直接内存:不属于jvm管理,

jvm运行时内存解析

一.jvm的概念 在了解jvm的概念之前,我们先来了解java平台的逻辑结构,图片来自<深入java虚拟机> 从图中我们可以看到jdk包含了jre,java语言和java开发工具和Api,jre包含了java运行的基础类库和java虚拟机,java虚拟机支撑着java程序的运行. jvm(java virtual machine)翻译为java虚拟机,从字面上来理解,jvm就是一个虚拟的机器,其实类似于一个操作系统,通过软件去虚拟出一个虚拟机,帮助我们管理计算机的内存和调用计算机的硬件等等.而

运行时内存模型

运行时内存模型运行时中,类型.对象.线程和托管对有相互的关系.CLR的一个windows进程,这个进程中可能存在多个现在.一个线程创建时,会分配1M的栈.这个栈主要用于方法传递实参和方法内部定义的局部变量.如果方法中有涉及到对象,则在堆中创建类型对象和类型实例.类型对象主要由类型对象指针.同步块索引.静态字段.方法列表组成.类型实例主要由类型对象指针.同步块索引.实例字段组成.其中类型实例的类型对象指针指向类型对象的类型对象指针.它们的相互关系如下图所示. 通过这张图,可以清楚了解运行时的内存由

对象与运行时内存

和大多数猴子一样,我原来也抵触对原理的学习, 后来发现掌握了原理才有了那种了然于胸,运筹帷幄的感觉,也就是顿悟. 这里主要介绍Java对象与运行时内存的知识. java运行时内存 Program Counter Registe(程序计数器): 记录当前线程执行字节码的位置,相当于行号指示器,为线程私有的. Java Virtual Machine Stacks(java虚拟机栈): 存放方法出口信息.局部变量表(对象引用.基本类型数据等),为线程私有的. Native Method Stack(

内存的划分 &amp; 程序代码运行时内存工作流程

内存的划分: 1,寄存器. 2,本地方法区. 3,方法区. 4,栈内存. 存储的都是局部变量. 而且变量所属的作用域一旦结束,该变量就自动释放. 5,堆内存. 存储是数组和对象(其实数组就是对象) ,凡是new建立的都在堆中. 特点: 1)每一个实体都有首地址值. 2)堆内存中的每一个变量都有默认初始化值,根据类型的不同而不同.整数是0,小数0.0或者0.0f,boolean类型是false,char类型是 '\u0000',引用数据类型是NULL 3)垃圾回收机制. 全局变量和局部变量的区别:

java运行时内存模式学习

学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoader被回收). Java堆(线程共享):存放对象实例和数组,这里是内存回收的主要地方.可以分为新生代(young)和年老代(tenured).从字面也可以知道,新生代存放刚刚建立的对象 而年老代存放长久没有被垃圾回收机制回收的对象.一般新生代有分为eden,from survivor和to sur

[转]JVM运行时内存结构

目录[-] 1.为什么会有年轻代 2.年轻代中的GC 3.一个对象的这一辈子 4.有关年轻代的JVM参数 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能.你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用,这样就会对堆的所有区域进行扫描.而我们的很多对象都是朝生夕死的,如果分代的话,我们把新创建的对象放到某一地方,当GC的时候先把这块存“朝生夕死”对象的区域进行回收,这样就会