当前位置:网站首页>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-2 LVS+DR概述与部署
- y86.第四章 Prometheus大厂监控体系及实战 -- prometheus存储(十七)
- 大型连锁百货运维审计用什么软件好?有哪些功能?
- Postgresql source code (66) insert on conflict grammar introduction and kernel execution process analysis
- 系统设计.如何设计一个秒杀系统(完整版 转)
- 用户与用户互发红包/支付宝C2C/B2C现金红包php源码示例/H5方式/兼容苹果/安卓
- Reproduce 20-character short domain name bypass
- [Ryerson emotional speaking/singing audiovisual dataset (RAVDESS)]
- docker安装mysql与宿主机相差8小时的问题。
- typescript type 和 interface 的区别
猜你喜欢
马尔可夫链
八年软件测试工程师带你了解-测试岗进阶之路
自定义通用分页标签02
MySQL query optimization and tuning
劝退背后。
Explain详解与实践
Significant differences between Oracle and Postgresql in PLSQL transaction rollback
出现504怎么办?由于服务器更新导致的博客报504错误[详细记录]
Postgresql source code (66) insert on conflict grammar introduction and kernel execution process analysis
自定义通用分页标签01
随机推荐
元宇宙“吹鼓手”Unity:疯狂扩局,悬念犹存
学会iframe并用其解决跨域问题
Mobile payment online and offline payment scenarios
new Date converts strings into date formats Compatible with IE, how ie8 converts strings into date formats through new Date, how to replace strings in js, and explain the replace() method in detail
Postgresql source code (66) insert on conflict grammar introduction and kernel execution process analysis
The general SQL injection flow (sample attached)
基于 SSE 实现服务端消息主动推送解决方案
7-1 LVS+NAT load balancing cluster, NAT mode deployment
typescript type 和 interface 的区别
The video of machine learning to learn [update]
怎么把elastic中的异常登录ip和日志自动导出或抓取到数据库中?
Basic characteristics of TL431 and oscillator circuit
How to automatically export or capture abnormal login ip and logs in elastic to the database?
Hey, I had another fight with HR in the small group!
The Shell function
系统设计.如何设计一个秒杀系统(完整版 转)
y86.第四章 Prometheus大厂监控体系及实战 -- prometheus存储(十七)
Take care of JVM performance optimization (own note version)
内网服务器访问远程服务器的端口映射
pnpm 是凭什么对 npm 和 yarn 降维打击的