当前位置:网站首页>Cache pool of unity framework
Cache pool of unity framework
2022-08-04 04:17:00 【Zero One and Black and White】
The cause of the buffer pool:
- 1、当newAfter an object is allocated a certain amount of space in memory,Even delete this object after use,The space in memory is also not freed,Just disconnected the reference relationship with this space,So the memory usage will keep going up.
- 2、Only when the memory usage reaches a certain amount, the garbage collection mechanism will trigger the garbage collection mechanism to release the useless memory,That is, it is triggered onceGC.触发GC需要进行大量的计算、Validation and the like filter out those useless data,这样就会对CPUcause a certain consumption,触发GCIt's easy to get stuck.
- 3、综上:为了解决这个问题,就需要减少new对象的次数,So the concept of buffer pool was born,I put a certain number of objects in advancenewCome out and put it in the buffer pool,This number is generally set,The footprint in memory is also fixed,于是,No more every time an object is needednew对象了,Instead, go to the cache pool to get the existing object.这样就避免了newThe memory space caused by the object keeps decreasing,This reduces triggeringGC的次数.
- 4、Caching is suitable for objects that need to be created and destroyed frequently.
Introduction to buffer pools
结构
整体结构
Buffer pool section
SpawnConifg的Inspector窗口编辑
| 接口 | Entity classes that inherit from interfaces |
|---|---|
| IObjectPooBuffer pool interface | ComponentPoolOfQueue、ComponentPoolOfStack、ObjectPoolOfQueue、ObjectPoolOfStack、 |
| SpwnItem实体类接口 | 这个就不写了 |
主要方法
| 类/接口 | 方法 | 属性 |
|---|---|---|
| Spawn.cs | 初始化(读取配置信息–>Add objects to the buffer pool)、取出对象、回收对象 | Dictionary<string, IObjectPool>A dictionary of buffer pools of type |
| IObjectPool | GetObject();取出对象、RecycleObject(T obj)回收对象 | |
| PoolBuilder | 默认数量、父级Transform | |
| ComponentPoolOfQueue | 三个构造方法(对象、固定数量的对象、对象数组、获取对象、回收对象 | 缓存的对象、对象栈、数量 |
| SpwnItem | 这个就不写了 |
相关知识点
Srack栈:
| 类/接口 | 方法 |
|---|---|
| Push() | Push对象插入Stack的顶部(入栈操作) |
| Pop() | 移除并返回Stack顶部的对象(出栈操作) |
| Peek() | 返回位于Stack顶部的对象,但不移除 |
| Contains() | Determine if an element existsStack中 |
| Clear() | 从StackMove all elements in the middle |
| Count() | 获取StackThe number of elements contained in |
ComponentPollOfStack.cs
孵化器:Manage buffer pools
1、Management inherited fromSpawnItemobject buffer pool,
2、The output is inherited fromSpawnItem对象
3、Recycling inherited fromSpawnItem对象
/** //孵化器,Used for output inherited fromSpawnItem的对象 */
public static class Spawn{
private static Dictionary<string, IObjectPool<SpawnItem>> SpwanPools;
//Incubator initialization
[AutoLoad(1)]
private static void Initialize(){
SpawnItem.OnRecycleEvent += RecycleObject;
SpawnPools = new Dictionary<string, IObjectPool<SpawnItem>>();
SpawnConfig spawnConfig = Resources.Load<SpawnConfig>("ScriptableObject/SpawnConfig");
foreach(var item in spawnConfig.Spawns){
if(string.IsNullOrEmpty(item.Prefab.ItemName)){
Debug.LogErrorFormat("对象名不能为空!Check the prefab {0} 的ItemName属性", item.Prefab.name);
break;
}
else if(SpawnPools.ContainsKey(item.Prefab.ItemName){
Debug.LogErrorFormat("Object name conflict!无法重复创建!Check the prefab {0} 的ItemName属性", item.Prefab.name);
break;
}
else{
SpawnPools.Add(item.Prefab.ItemName, new ComponentPollOfStack<SpawnItem>(item.Count, item.Prefab));
}
}
}
//取出对象
public static T GetObject<T>(string name) where T : SpawnItem{
SpawnItem item = SpawnPools[name].GetObject();
item.IsAllowRecycle = true;
if(item is T){
return item as T;
} else {
return null;
}
}
//回收对象
private static void RecycleObject(SpawnItem symbol){
SpawnPools[symbol.ItemName].RecycleObject(symbol);
}
}
ComponentPollOfStack.cs
1、对象缓存池
2、ComponentPoolOfQueue、ObjectPoolOfQueue、ObjectPoolOfStack类似
/** //对象缓存池 */
public class ComponentPoolOfStack<T> : PoolBuilder, IObjectPool<T> where T :Component, new(){
//保存的对象
private T template;
//对象栈
protected Stack<T> Pool;
//栈长
public int Count {
get {
return Pool.Count;}}
//有参构造
public ComponentPoolOfStack(T obj){
template = obj;
Pool == new Stack<T>(MAXCOUNT);
for(int i=0; i < MAXCOUNT; i++){
T newObj = Object.Instantiate(template, Parent);
RecycleObject(newObj);
}
}
//有参构造
public ComponentPoolOfStack(int count, T obj){
template = obj;
MAXCOUNT = count;
Pool == new Stack<T>();
for(int i=0; i < MAXCOUNT; i++){
T newObj = Object.Instantiate(template, Parent);
RecycleObject(newObj);
}
}
//取出对象(出栈)
public T GetObject(){
T obj = null;
if(Pool.Count <= 0)
obj = Object.Instantiate(template, Parent);
else
obj = Pool.Pop();
obj.gameObject.SetActive(true);
return obj;
}
//回收对象(入栈)
public void RecycleObject(T obj){
if(Pool.Count >= MAXCOUNT){
Object.Destroy(obj,gameObject);
return;
}
obj.gameObject.SetActive(false);
obj.transform.SetParent(Parent);
obj.transform.localPosition = Vector3.zero;
obj.transform.rotation = Quaternion.identity;
Pool.Push(obj);
}
}
PoolBuilder.cs
Declare some default properties required by the buffer pool
public class PollBuilder{
protected int MAXCOUNT = 15;
private static Transform parent = null;
public static Transform Parent {
get {
return parent; } }
}
IOjectPool.cs
Buffer pool interface,Some buffer pool methods are declared
public interface IObjectPool<T>{
//取出对象(出栈)
T GetObject();
//回收对象(入栈)
void RecycleObject(T obj);
}
SpawnConfigEditor
管理SpawnConfig(ScriptableObject)The data problem in the window editor
[CustomEditor(typeof(SpawnConfig))]
public class SpawnConfigEditor : Editor
{
private SpawnConfig spawn;
private void OnEnable(){
spawn = target as SpawnConfig;
}
public override void OnInspectorGUI(){
//实现EditorSome are already setInspector定义
base.OnInspectorGUI();
//Get a button style
GUIStyle style = GUI.skin.GetStyle("Button");
style.fontSize = 20;
//是否点击:按钮(按钮的文本,按钮的样式,高度(new一个高度))
//Roughly readPrefabs中的所有数据,Then put these data inSpawnItemType data into aSpawnConfig类型的参数中,然后更新到ScriptableObject资源文件夹中
if (GUILayout.Button("更新Spawn列表", style, new[] {
GUILayout.Height(50)})){
List<SpawnItem> items = new List<SpawnItem>();
//路径
string root = Application.dalaPath + "/Prefabs";
//是否存在此路径
if (Directory.Exists(root)) {
//Get all file pathnames in the current directory(包括文件夹)
string[] paths = Directory.GetFiles(root, "*", SearchOption.AllDirectories);
for (int i = 0; i < paths.length; i++) {
//Cutting path name
string path = path[i].Substring(paths[i].IndexOf("Assets"));
//IO:根据(路径名、泛型)加载数据
SpawnItem item = AssetDatabase.LoadAssetAtPath<SpawnItem>(path);
if (item != null) {
items.Add(item);
}
}
List<SpawnConfig.SpawnNode> nodes = new List<SpawnConfig.SpawnNode>(item.Count);
for (int i = 0; i < items.Count; i++) {
int count = 15;
for (int j = 0; i < spawn.Spawns.Count; j++){
if(spawn.Spawns[j].Prefab.ItemName.Equals(items[i].ItemName)){
count = spawn.Spawns[j].Count;
break;
}
}
SpawnConfig.SpawnNode node = new SpawnConfig.SpawnNode();
node.Prefab = items[i];
node.Count = count;
nodes.Add(node);
}
spawn.Spawns = nodes;
}
EditorUtility.SetDirty(spawn);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
style.fontSize = 12;
}
[MenuItem("Tools/CreateSpwanConfig")]
public static void CreateAudioConfig(){
string path = "Assets/Resources/ScriptableObject/SpawnConfig.asset";
string directory = Application.dataPath + "/Resources/ScriptableObject";
if(!File.Exists(path))
{
Directory.CreateDirectory(directory);
AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<SpawnConfig(), path>);
AssetDatabase.Refresh();
}
else
{
#if UNITY_EDITOR
Debug.LogWarning("SpawnConfig已存在,不允许重复创建");
#endif
}
}
}
需要了解的API
using System
using UnityEditor
Editor接口
边栏推荐
- RSS订阅微信公众号初探-feed43
- 【id类型和NSObject指针 ObjectIve-C中】
- 深度学习——以CNN服装图像分类为例,探讨怎样评价神经网络模型
- The video of machine learning to learn [update]
- 用户与用户互发红包/支付宝C2C/B2C现金红包php源码示例/H5方式/兼容苹果/安卓
- Hey, I had another fight with HR in the small group!
- Mockito unit testing
- 高效IO模型
- PL/SQL Some Advanced Fundamental
- Tensors - Application Cases
猜你喜欢

系统设计.秒杀系统

Reproduce 20-character short domain name bypass

【 observe 】 super fusion: the first mention of "calculate net nine order" evaluation model, build open prosperity of power network

JVM笔记

Functions, recursion and simple dom operations

Take care of JVM performance optimization (own note version)

MySQL query optimization and tuning
![[Ryerson emotional speaking/singing audiovisual dataset (RAVDESS)]](/img/f7/78eea9f14ca97b5e78592c7c2be313.png)
[Ryerson emotional speaking/singing audiovisual dataset (RAVDESS)]

pnpm 是凭什么对 npm 和 yarn 降维打击的

42. 接雨水
随机推荐
元宇宙“吹鼓手”Unity:疯狂扩局,悬念犹存
数据集类型转换—TFRecords文件
嵌入式数据库开发编程MySQL(全)
Simple operation of the file system
[Medical Insurance Science] To maintain the safety of medical insurance funds, we can do this
自定义通用分页标签01
MySQL Query Exercise (1)
[Ryerson emotional speaking/singing audiovisual dataset (RAVDESS)]
docker+bridge+redis master-slave+sentry mode
How to automatically export or capture abnormal login ip and logs in elastic to the database?
移动支付线上线下支付场景
FFmpeg —— 录制麦克风声音(附源码)
if,case,for,while
打造一份优雅的简历
Jenkins 导出、导入 Job Pipeline
网络工程师入门必懂华为认证体系,附系统学习路线分享
42. 接雨水
centos 安装postgresql13 指定版本
文件系统的简单操作
Implementing a server-side message active push solution based on SSE