很久以前我写了一个对象池系统(好吧,大部分都是 - 当时我需要的部分)。现在程序已经发展了,我发现了一个我在实现池时没想到的缺陷。
本质上,池将一个对象作为构造函数,并使用反射克隆它以生成该对象的数组。这是在池中创建对象的函数的实现:
poolSize i = 0;
T[] oldData = null;
if (this.chunks != null && this.chunks.Length > 0)
{
oldData = new T[this.depth];
Array.Copy(this.chunks, oldData, this.chunks.Length);
}
this.chunks = new T[this.depth + this.depthIncrement];
if (oldData != null)
{
Array.Copy(oldData, this.chunks, oldData.Length);
}
for (i = this.depth; i < this.depth + this.depthIncrement; i++)
{
this.chunks[i] = Cloner.CloneObjectWithIL(this._template);
this.freeQueue.Add(i);
}
this.depth += this.depthIncrement;
现在,检查Object.ReferenceEquals(pool.chunks [0],pool.chunks [1])会返回false - 所以看起来数组的每个索引都是它自己的对象,而不仅仅是一堆引用对象
现在在主代码中,我们使用GetObject方法从池中获取对象:
public T GetObject(T tmp)
{
T retObj = tmp;
this.chunks[this.volume] = retObj;
this.usedQueue.Add(this.volume);
this.volume++;
return retObj;
}
我遇到了一些受保护的内存错误(C#等效于SEGFAULT?)所以我接着做了一些调试。所以我使用了我通常不会做的代码,因为它违背了池背后的一些目的:
Map.Entity tmp = Map.Entity.EntityPool.chunks[0];
tmp.SetPosition(m, 1, 9);
现在,当我在此之后添加一个断点并查看chunks数组时,chunks数组的每个元素的位置都是(1,9),当它们都应该是(0,0),而不是索引0。 / p>
我在这里缺少什么?