缓存池
项目中一种缓存池
缓存池主要用来回收和分配对象,避免频繁创建对象。使用缓存池的原因是一方面创建对象存在消耗(详细什么消耗暂且不清楚),另一方面在C#中过多只用过一次的对象会增加GC。
缓存池也有很多细节,当缓存池对象被用完了,一种处理方式可以扩大缓存池容量,即new新的对象分配出去;另一种处理方式,也是今天学到的,可以利用优先队列,将使用频率最低的对象淘汰出去,不改变缓存池的容量,当然这种情况下的缓存池本来就有尽量不改变对象字段属性等的需求。
C#代码如下:
//要缓存处理的对象,对象的id不可被改变,只有在初始化时赋值。
public class Target{
public int id {get;private set;}
public Target(int i)
{
id=i;
}
}
//缓存池
public class TargetCahce{
const int cacheSize=64;
static LinkedList<int> cacheQueue=new LinkedList<int>();
static Dictionary<int,Target> cache=new Dictionary<int,Target>(cacheSize);
public static Target GetTarget(int id)
{
Target unit=null;
cache.TryGetValue(id,out unit);
if(unit==null)
{
//当池子满了,将链表尾部淘汰替换
if(cache.Count>=cacheSize)
{
cache.Remove(cacheQueue.Last.Value);
cacheQueue.RemoveLast();
}
unit=new Target(id);
cache.Add(id,unit);
}
//刚被使用的对象都移到链表头部
if(cacheQueue.Count==0) cacheQueue.AddFirst(id);
else MoveFirst(id,cacheQueue);
return unit;
}
static void MoveFirst(int id,LinkedList<int> cacheQueue)
{
LinkedListNode<int> existId=null;
do
{
if(existId.Value==Id) break;
existId=existId.Next;
}
while(existId!=null);
if(existId!=null)
{
cacheQueue.Remove(existId);
cacheQueue.AddFirst(existId);
}
else cacheQueue.AddFirst(Id);
}
}
其实这个本质就和内存换页算法中LRU链表形式一样。链表保存的是优先级信息,用来决策当缓存池满是那个对象被代替。在我们案例中是将距离当前最长时间没有使用的对象给淘汰替换掉。每次刚被使用的对象放到链表头。