缓存池随笔
Posted jay-auditore
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存池随笔相关的知识,希望对你有一定的参考价值。
这周学习unity框架第二课——缓存池模块。(周更它来了)
为什么需要缓存池
c#中清理一次内存叫做一次GC,由于内存的固定的,当内存使用到达上线时,c#会清理一些暂时没有用的实例化对象,GC操作会造成明显卡顿。如果实例化的对象很多,那么卡顿现象将会十分明显而且频繁。这时候,我们引入缓存池。实例化对象暂时没用时,将它放入缓存池里面;需要用到时,就将它从缓存池里拿出来。引入缓存池之后,实例化对象的出现和移走将有序的进行,GC的频率大大减少,每一个实例化对象都能最大利用,是一个优化内存使用的方法。
照例一段模仿代码
/// <summary>
/// 缓存池模块
/// </summary>
public class PoolManager : BaseManager <PoolManager>
{
public Dictionary< string, List< GameObject > > poolDic = new Dictionary< string, List< GameObject > >();
/// <summary>
/// 往外拿东西
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public GameObject GetObj( string name )
{
GameObject Obj = null;
if( poolDic.ContainsKey(name) && poolDic[name].Count > 0 )
{
Obj = poolDic[name][0];
poolDic[name].RemoveAt(0);
}
else
{
Obj = GameObject.Instantiate(Resources.Load<GameObject>(name));
}
//激活
Obj.SetActive(true);
return Obj;
}
/// <summary>
/// 还暂时不用的东西给我
/// </summary>
public void PushObj( string name, GameObject Obj)
{
//失活
Obj.SetActive(false);
//里面有抽屉
if(poolDic.ContainsKey(name))
{
poolDic[name].Add(Obj);
}
//里面没有抽屉
else
{
poolDic.Add(name, new List<GameObject>(){ Obj });
}
}
}
要理解这段代码,可以把内存池理解为一个衣柜,里面有许多抽屉,放不同品种的衣服。如果实例化了一个GameObject 1,使用结束之后想放入衣柜(缓存池)中,首先检测有没有一个抽屉是放GameObject 1的:如果有,就放进去那个抽屉;没有,就创建一个抽屉,专门放GameObject 1,然后再把GameObject 1放进去。在这之后你再实例化一个GameObject 1,使用结束之后就会放进缓存池中一个叫GameObject 1的抽屉里面。如果你下一个实例化的是GameObject 2,同样,先检测衣柜(缓存池)中有没有GameObject 2的抽屉:有,放进去;没有,创建一个专门放GameObject 2的抽屉,再放进去。通过这样的存放机制,内存的使用变得高效合理,玩家玩游戏的时候就不会经常觉得卡顿了。
还有一个细节,就是PoolManager它继承了BaseManager[1],至于这个BaseManager可以看 上一篇博客。
总结
这一节对我这样的小白来说有点难理解= =,但是去把dictionary
的知识补上之后,再看代码就能理解80%以上了。这一节的缓存池只是最简单的实现,下一节中会对它进行优化,敬请期待。
单例模式基类 ??
以上是关于缓存池随笔的主要内容,如果未能解决你的问题,请参考以下文章
(13) PHP 随笔---Smarty模板引擎 缓存的高级应用 22