缓存池随笔

这周学习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%以上了。这一节的缓存池只是最简单的实现,下一节中会对它进行优化,敬请期待


  1. 单例模式基类 ↩︎

posted @ 2020-04-26 20:01  Jay_Auditore  阅读(191)  评论(0编辑  收藏  举报