zoukankan      html  css  js  c++  java
  • 缓存池模块基础

    缓存池模块基础

     

    当我们利用c#代码实例化对象时,内存空间中就会开辟一个区域用于储存实例化相关的信息,即使当我们删除这个实例化对象后,也只是断开了对内存空间中对应区域的引用,并没有真正地释放内存空间。

    C#的内存空间机制:

    当所有可用的内存空间都被占用时,才会去释放那些已经不会再使用的区域,用于储存新的信息。我们把这一过程叫做GC。

    由于每一次GC时,系统需要重新检测大量的信息来判断是否有用,并删除,所以会对CPU产生巨大的损耗。通常情况下,每一次GC都会伴随着一点点的卡顿。

    所以为了避免这一情况的发生,就需要使用到缓存池

    缓存池的作用:

    缓存池就好比我们的工具箱,当我们第一次实例化某一对象时,就像制造某一个工具,这时就在内存空间开辟一个新区域。而当我们对这一实例化对象进行删除时,缓存池就会记录下这一实例化对象的信息,也就是将这个工具装进了工具箱,当我们需要再次实例化这一对象时,就不需要重新在内存空间里开辟新区域,而是直接在缓存池里找出内存空间之前的区域调用的就行了,也就是把工具从工具箱里取出来继续使用就行了。

    好处:

    从短期来讲,这样会使内存空间中总有几个区域是一直被占据的,有点浪费内存,但从长期来讲这样做可以极大地减缓内存空间填满的时间,加长了每一次GC的间隔时间,减少有限时间内卡顿的次数。


    相关的例子代码

    缓存池模块:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    /// <summary>
    /// 缓存池模块
    /// </summary>
    public class PoolMgr :BaseManager<PoolMgr>
    {
       //缓存池容器(衣柜)
       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.name = 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 });
          }
      }
    }

    生成,从缓存池中取出

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class Test : MonoBehaviour
    {
       // Start is called before the first frame update
       void Start()
      {
           
      }

       // Update is called once per frame
       void Update()
      {
           if (Input.GetMouseButtonDown(0))
          {
               PoolMgr.GetInstance().GetObj("Cube");
          }
           if (Input.GetMouseButtonDown(1))
          {
               PoolMgr.GetInstance().GetObj("Sphere");
          }
      }
    }

    移出,放进缓存池

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class DelayPush : MonoBehaviour
    {
       // 当对象激活时,会进入的生命周期函数
       void OnEnable()
      {
           Invoke("Push", 1);//延迟一秒调用函数
      }

       void Push()
      {
           //放回缓存池
           PoolMgr.GetInstance().PushObj(this.gameObject.name, this.gameObject);
      }
    }

  • 相关阅读:
    sql参数化查询语句
    委托窗体之间的传值
    js交换变量写法
    win8环境下安装sql2008r2
    无法绑定由多个部分组成的标识符“System.Data.DataRowView” 遇到问题转帖
    利用stringBuilder操作html文件
    阿里云 发送手机短信
    在定时器中service注入不进去的解决方案
    mysql 排序后在查询
    Hibernate使用Criteria实现分页
  • 原文地址:https://www.cnblogs.com/wei1349/p/12771070.html
Copyright © 2011-2022 走看看