
哦了这次是引用池模块这个模块主要的目的就是创建某一个类对象的时候让它从这个池里创建当引用对象不需要的时候不是让它引用滞空然后交给GC而是放到引用池里当再需要这个对象的时候就从引用池里取一个而不是在外面new一个。IReference.cs引用类型的具体引用对象需要继承这个接口才能被引用池管理。要求一个Clear方法意思就是不需要这个对象的时候让这个对象在被引用池回收之前跑一个clear方法。ReferencePoolInfo.cs这是一个数据结构类型脚本主要是相当于在之后ReferencePool需要某一个对象的信息的时候把这个对象的信息写到这个结构体对象里然后通过得到这个结构体对象来获得里面的信息相当于返回了英一个包然后解包读取。而且因为是结构体对象更适合只用来观察而不是使用。type是这个类对象所对应的类型因为这个类型的类对象可能会有很多个。然后就是构造函数和这些成员对应的属性。ReferencePool.CS首先它是一个分部类在另一个ReferencePool类下有一个ReferenceCollectionReferenceCollection是引用的具体池对象而ReferencePool主要是池。ReferenceCollection.cs每一个实现了 IReference 的类型在 ReferencePool 内部都有一个对应的 ReferenceCollection可以理解为“该类型专属的仓库”。这个仓库内部用一个栈Queue)来保存当前空闲的对象实例。当外部需要该类型的对象时通过 ReferencePool.Acquire() → 找到对应的 ReferenceCollection → 从Queue弹出一个空闲对象若空则 new 一个。用完对象后通过 ReferencePool.Release(T) → 找到对应的 ReferenceCollection → 调用对象的 Clear() 方法重置状态 → 把对象压回Queue中等待下次复用。通过这种方式大幅减少 new 的次数从而实现近乎零 GC 的引用对象复用。要注意不管弹出的对象还是压到对象池的对象这些所有对象都是在m_References里管理的如果需要就从这个Queue里弹出然后计数如果要回收就加到这个Queue里。如上用m_References存储当前类型引用池对应的所有对象。m_ReferenceType是当前ReferenceCollection在ReferencePool里对应的类型。m_UsingReferenceCount是正在使用的引用对象的数量(引用池弹出的)。m_AcquireReferenceCount表示获取走的对象的数量这个参数主要用于调试时候看这个类型的引用池被取了多少次。m_ReleaseReferenceCount表示已经回收到池里对象的数量统计回收的次数。m_AddReferenceCount表示当前引用池添加了多少次对象。m_RemoveReferenceCount表示要从这个池子移除对象的次数。上面是这些变量的属性。之后创建这种引用类型对象就是通过引用池并且引用池会保管好它们。UnusedReferenceCount 是获取当前类型引用池未使用的对象的数量。UsingReferenceCount 是获取当前使用中的当前类型的引用的数量。AcquireReferenceCount “外部获取的引用对象” 的数量。ReleaseReferenceCount 回收到引用池的次数。AddReferenceCount 添加到引用池的对象的数量。RemoveReferenceCount 从引用池移除的对象的数量。比如我刚开始引用池是空的那么添加几个对应类型的对象m_AddReferenceCount就增加添加到m_References里通过UnusedReferenceCount可以获取到未被使用的对象的数量假设外部获取对象了就从m_References里Dequeue那么UnusedReferenceCount的数量就减少m_UsingReferenceCount的数量就增加了之后这个对象使用完成了Release到引用池里那么就回到m_References里面m_UsingReferenceCount(正在使用的对象)的数量就减少了并且因为回到了集合里UnusedReferenceCount获取的时候数量就增加了。这个方法是从这个类型的池子里获取对象泛型要求是继承IReference并且是类对象并且有无参构造。判断一下泛型类型是不是当前对象池的类型如果不是就抛出错误。那么既然是获得对象那么m_UsingReferenceCount正在使用的对象就加1外部从引用池获取到的对象数量也加1。然后通过m_References锁住线程让其他线程不能获取m_References然后查看引用池里对象是否大于0如果大于0就直接从m_References里弹一个对象返回出去并且转换为需要的类型。如果没有走return那么就new一个对应泛型的对象返回出去在这之前给m_AddReferenceCount加1表示这个对象池实际要管理的实例加1。这个也是获取对象方法在获取之前将 “正在使用的对象数量” 和 “获取走的数量” 加1。然后还是查看m_References里有没有如果有就直接从m_References里弹出一个使用如果没有的话就使用反射创建一个当前对象池对应类型的对象再返回这里就不通过泛型了而是在外面直接指导这个引用池对应的类型是什么了然后直接获取。在返回之前告诉对象池这个类型管理的数量加1了。回收对象先执行引用对象在回收前需要执行的Clear方法(感觉有点像更明确的虚构函数明确知道对象不需要之前能做的内容)。然后锁住线程(m_EnableStrictCheck是在ReferencePool.cs类里的成员用来查看是否需要严格验证如果为true会在添加内容的时候对添加的元素进行更多步骤的验证)然后判断m_References里有无要回收的这个对象如果开了严格验证并且引用池里有这个要回收的对象了说明这个对象已经回收了那么对象就不能再回收了就抛出错误该对象已经在对象池里。如果没有开严格验证或者当前对象没有在引用池里那么就把这个对象加到m_References里。之后将m_ReleaseReferenceCount也就是已回收对象的数量加1然后正在使用的数量减1。往对象池里添加引用类型对象通过泛型指定的形式首先判断类型不是m_ReferenceType对应类型就抛出异常。然后锁住线程往m_References里添加添加count个。并且添加时候让m_AddReferenceCount也添加count个表示当前引用池管理的当前类型对象的数量。这个Add方法可以用来初始化对应类型引用池的初始数量会将引用类型对象创建好加到m_References里并且获取引用池未使用的对象的数量UnusedReferenceCount时也不需要再在Add方法里写因为新添加的这些对象本身就没有被Arquire过比如初始化加了20个新对象那么获取UnusedReferenceCount属性的时候就会返回20。这个也是添加方法直接锁住线程添加当前引用池对应的类型count个然后m_AddReferenceCount计数增加表示当前引用池管理的对象个数。移除对象表示有count个对象被移除锁住线程先判断要移除的对象数量是否比总体数量大如果count比引用池数量还多那就把要移除的数量改成当前引用池对应最大数量。然后移除了的引用对象数量增加count个。然后循环count次从对象池里移除对象让这些对象拾取引用也就是等着被GC了。RemoveAll也是同样的道理先获取引用池中的对象的数量然后全清空掉。然后就是在引用池里的每一个引用类型对象都是全新的一个对象也就是它们的值都是默认的所以Remove里没有写调用对象的Clear因为在Release到引用池的时候就已经执行过这个回收的对象的Clear方法了那么说明这个引用类型对象在创建到引用池、回收到引用池里的时候都是Default的。ReferencePool.cs这个类是引用池的主类上面那个ReferenceCollection是为了这个类来服务的目的就是让一个Type对应一个ReferenceCollectionReferenceCollection可以有多个对象。s_ReferenceCollections表示引用池管理的所有类型和对应的对象。m_EnableStrictCheck用于控制是否开启严格模式。获取是否开启严格模式获取引用池所有类型的数量(注意是所有类型的数量)。。这个也是获取只不过没有通过泛型约束来判断类型而是通过先调用强制验证然后再获取对应类型的引用池对象。这个是回收传递的内容是对应类型引用池的对象先获取这个对象的类型信息然后强制验证一下是否是类对象是否不是抽象类型是否继承IReference满足条件后加到对应类型引用池里面。向对应类型引用池里添加count个引用类型对象没有使用泛型的那个方法里面执行强制验证。从对应类型引用池中移除对应数量的对象。接下来稍微使用一下这个引用池吧。由此可见引用池这个静态类可以完美管理引用类型对象不用就回收使用就创建也可以提前添加对象数量如果Arquire的时候对应引用池对象数量不够内部会自己添加。