当前位置:网站首页>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接口
边栏推荐
- 7.LVS负载均衡群集之原理叙述
- 将xml标签转换为txt(voc格式转换为yolo方便进行训练)
- How to automatically export or capture abnormal login ip and logs in elastic to the database?
- 用户与用户互发红包/支付宝C2C/B2C现金红包php源码示例/H5方式/兼容苹果/安卓
- MySQL query optimization and tuning
- mq应用场景介绍
- 十一种概率分布
- "Introduction to nlp + actual combat: Chapter 8: Using Pytorch to realize handwritten digit recognition"
- Explain detailed explanation and practice
- 深度学习之 10 卷积神经网络3
猜你喜欢
随机推荐
备份工具pg_dump的使用《postgres》
[Ryerson emotional speaking/singing audiovisual dataset (RAVDESS)]
Senior PHP development case (1) : use MYSQL statement across the table query cannot export all records of the solution
软件测试如何系统规划学习呢?
SVM介绍以及实战
7-2 LVS+DR Overview and Deployment
7.LVS负载均衡群集之原理叙述
ADC噪声全面分析 -03- 利用噪声分析进行实际设计
数据集类型转换—TFRecords文件
Jenkins 导出、导入 Job Pipeline
if,case,for,while
Structure function exercise
Postgresql源码(66)insert on conflict语法介绍与内核执行流程解析
pnpm 是凭什么对 npm 和 yarn 降维打击的
MRS: Introduction to the use of Alluxio
【技巧】借助Sentinel实现请求的优先处理
y86.第四章 Prometheus大厂监控体系及实战 -- prometheus存储(十七)
The general SQL injection flow (sample attached)
文件内容的操作
go module的介绍与应用