翻开秘籍第一页:
问: 什么是类对象池?
剑之初: 游戏中,我们常常会遇到频繁得创建和销毁大量相同对象的场景。如果我们不做任何的特殊处理,这种场景会出现两个性能问题——大量的内存碎片以及频繁的分配内存空间。 而对象池能供完美得解决这两个问题。
翻开秘籍第二页:
问: 什么原理?
剑之初: 当创建对象时,对象池将对象放入池管理的某种内存连续的数据结构中(数组或者栈等)。当不需要对象时,对象池并不销毁对象,而是将对象回收到池中,下次需要的时候再次从池中拿出来。
因为,对象储存在内存连续的数据结构中,所以解决了内存碎片的问题。
因为,对象每次用完以后就放回池中循环利用而不是再次创建和销毁,这样就解决了频繁的内存分配和销毁的问题。
翻开秘籍代码页:
#region 模块信息
//===================================================
// Copyright (C) 2020
//
// 文件名(File Name): ClassObjectPool.cs
// 作者(Author): 稀饭
// 邮箱(e-mail): 1144000915@qq.com
// 创建时间(CreateTime): 2020-12-22 13:53:04
// 修改者列表(modifier):
// 模块描述(Module description): 创建脚本自动修改文件名、作者、创建时间
//===================================================
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YouYou
{
/// <summary>
/// 类对象池
/// </summary>
public class ClassObjectPool : IDisposable
{
private Dictionary<int, Queue<object>> m_ClassObjectPoolDic;
public ClassObjectPool()
{
m_ClassObjectPoolDic = new Dictionary<int, Queue<object>>();
}
/// <summary>
/// 取出一个对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Dequeue<T>() where T:class,new()
{
lock(m_ClassObjectPoolDic)
{
//先找到这个类对应的哈希值
int key = typeof(T).GetHashCode();
Queue<object> queue = null;
m_ClassObjectPoolDic.TryGetValue(key, out queue);
if(queue==null)
{
queue = new Queue<object>();
m_ClassObjectPoolDic[key] = queue;
}
//获取对象
if(queue.Count>0)
{
//说明队列中 有闲置的
return (T)queue.Dequeue();
}else
{
//如果队列中没有 实例化一个
return new T();
}
}
}
/// <summary>
/// 对象回池
/// </summary>
/// <param name="obj"></param>
public void Enqueue(object obj)
{
//先找到这个类对应的哈希值
int key = obj.GetType().GetHashCode();
Queue<object> queue = null;
m_ClassObjectPoolDic.TryGetValue(key, out queue);
if (queue != null)
{
queue.Enqueue(obj);
}
}
public void Dispose()
{
m_ClassObjectPoolDic.Clear();
}
}
}
翻开秘籍代码注解页:
问: 外部如何调用呢?
剑之初:
GameEntry.Pool.Dequeue(); 从类对象池中取出类对象
GameEntry.Pool.Enqueue(action); 对象回池
#region 模块信息
//===================================================
// Copyright (C) 2020
//
// 文件名(File Name): TimeComponent.cs
// 作者(Author): 稀饭
// 邮箱(e-mail): 1144000915@qq.com
// 创建时间(CreateTime): 2020-12-15 16:10:51
// 修改者列表(modifier):
// 模块描述(Module description): 时间组件
//===================================================
#endregion
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace YouYou
{
/// <summary>
/// 时间组件
/// </summary>
public class TimeComponent : YouYouBaseComponent, IUpdateComponent
{
protected override void OnAwake()
{
base.OnAwake();
GameEntry.AddUpdateComponent(this);
m_TimeManager = new TimeManager();
}
#region 定时器
/// <summary>
/// 定时器管理器
/// </summary>
private TimeManager m_TimeManager;
/// <summary>
/// 创建定时器
/// </summary>
/// <returns></returns>
public TimeAction CreateTimeAction()
{
return GameEntry.Pool.Dequeue<TimeAction>();
}
/// <summary>
/// 注册定时器
/// </summary>
/// <param name="action"></param>
internal void RegisterTimeAction(TimeAction action)
{
m_TimeManager.RegisterTimeAction(action);
}
/// <summary>
/// 移除定时器
/// </summary>
/// <param name="action"></param>
internal void RemoveTimeAction(TimeAction action)
{
m_TimeManager.RemoveTimeAction(action);
GameEntry.Pool.Enqueue(action);
}
#endregion
public void OnUpdate()
{
m_TimeManager.OnUpdate();
}
public override void Shutdown()
{
m_TimeManager.Dispose();
}
}
}