缓存碎语一

如果按存储的地方来分类,缓存分为哪些?

 

分为本地缓存和分布式缓存。本地缓存就是把数据保存应用程序所在的那台机器的内存中;而分布式缓存是把数据放在缓存服务器中,这个缓存服务器有可能是和应用服务器在同一台机器,这时候的是跨进程访问,如果缓存服务器和应用程序服务器不在同一台机器,这时候就可能会设计到跨域跨进程访问了。

 

缓存通过何种方式来找到缓存中的数据?

 

表面上是通过键来找到对象,实际是通过对象的引用在内存中查找到数据对象的。

 

修改缓存对象和修改数据库数据是一回事吗?

 

千万不要认为修改缓存对象就是修改了数据库中对应的数据。如果修改的是本地缓存对象,那只是修改更新了内存的那个缓存对象。而对于分布式缓存,在应用程序中修改完缓存对象,还需要把新的对象数据传给跨域、跨进程之外的缓存服务器。

 

有哪些分布式缓存机制?

 

比如memcached,AppFabric......

 

分布式缓存保存和读取数据的大致过程是怎样的?

 

缓存数据的时候,使用API,在应用程序服务器上把数据序列化为字节,再把这些字节发送给缓存服务器,让其保存;读取缓存数据的时候,缓存服务器把对象对应的字节发送给应用程序,在应用程序服务器上的对应类库再把字节转换成对象。

 

.NET本地缓存有哪几种方式?

 

一种是给类打上Serializable特性,不过这种方式由于其内部使用了反射机制,会比较耗CPU,特别是处理大对象的时候;另一种方式是给类打上Serializable特新,并且还让这个类实现ISerializable接口,这种方式没有使用反射,效率是上一种方式的几百倍。

 

什么是缓存大对象?

 

当缓存对象占用的内存大于85K的时候,就把其认为是缓存大对象。注意,大于85*1024个字节是大对象,一个对集合的引用,比如List<Person> list = new List<Person>(),其中list只是指向托管堆上的一个引用,不是大对象。

 

大对象与内存碎片,内存碎片是如何产生的?

 

大对象是被放在托管堆上的大堆上的,当GC进行垃圾回收后,大堆是不会被压缩的。内存碎片的产生大致这样:

→产生大对象
→在内存空间为该大对象开辟一块连续的区域
→CLR的GC进行垃圾回收,对象被回收,内存上该对象对应的大堆没有被压缩,这块内存空间还一直存在的
→在产生一个比第一次小的对象,占用刚才大堆内存空间的一部分
→于是,剩下的大堆内存空间的那部分成了碎片

 

线程间共享缓存数据会造成冲突吗?

 

答案是会的。

 
 
......
int a = 0;
myCache["mykey"] = 0;
 
 
var thread1 = new Thread(new ThreadStart(() =>{
    a = myCache["mykey"];
    a++;
    myCahce["mykey"]=a;
}));
 
 
var thread2 = new Thread(new ThreadStart(() =>{
    a = myCache["mykey"];
    a++;
    myCahce["mykey"]=a;
}));
 
 
thread1.Start();
thread2.Start();
 
 
 
 

最终的结果可能是0也可能是1。

 

调用缓存API把数据缓存起来后,就一定能读取到吗?

 

不一定。因为缓存机制一般设置绝对或相对过去时间,一旦过了这个时间,缓存数据就没有了。另外,缓存服务器CPU忙、网络不好也会导致数据没有被即时序列化保存到缓存服务器中。

所以,每次使用缓存数据的时候,先要判断缓存数据是否存在。

 

参考资料:汪洋的"DotNet"公众号。

转载于:https://www.cnblogs.com/darrenji/p/4330558.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值