我编写了一个简单的对象池管理器,用于根据需要将包含在非常简单的类中的顶点缓冲区分开。一切正常,除了看起来被返回的对象被某种方式复制而不是被引用,因为内存使用意外地上升。池中的所有对象都在运行时在沼泽标准列表中实例化。这是初始化代码:
public static void InitVBPoolManager()
{
int i;
// INIT POOL VB OBJECT LIST
VBPool = new List<PoolManagerVBObject>();
VBPool.Capacity = POOL_CAPACITY;
// INIT POOL INDEX POINTERS
nextItemIndex = 0;
// FILL POOLMANAGER WITH INITIAL BATCH OF VBO
for (i = 0; i < POOL_CAPACITY; ++i)
{
VBPool.Add(new PoolManagerVBObject(VERTEX_BUFFER_SIZE,0));
}
}
这是Get Object方法:
public static PoolManagerVBObject GetVB()
{
// RETURN POOL VB
if (nextItemIndex < POOL_CAPACITY)
{
VBRecycled++;
return VBPool[nextItemIndex++];
}
else
{
VBPool.Add(new PoolManagerVBObject(VERTEX_BUFFER_SIZE,0));
POOL_CAPACITY++;
VBCreated++;
return VBPool[nextItemIndex++];
}
}
最后使用对象的代码:
for (j = 0; j < limit; ++j)
{
if (thisChunk.voxelVB.Count <= j)
{
thisChunk.voxelVB.Add(VBPoolManager.GetVB());
}
似乎在调用GetVB()时,返回的对象正在复制,因为大约需要260MB的RAM。这显然不应该发生,因为已经在PoolManager中创建了对象。如果我用一个新对象替换GetVB()调用()内存消耗是相同的,这就是为什么我被引导相信正在制作副本。有人有任何想法吗?
答案 0 :(得分:0)
此实现将始终泄漏内存。您永远不会从池中删除引用,也永远不会将对象返回池中。
正确实现的对象池只能保存对可用对象的引用。从池中检索对象时,不应该再引用它。这样,对象可以被垃圾收集,以防它们没有返回池中。这指向另一个问题 - 您似乎没有办法将对象返回池中。
此外,您的池不是线程安全的。
如果您想了解如何正确实现对象池,可以查看Roslyn ObjectPool
答案 1 :(得分:0)
这是池管理器代码的dispose方法:
update_time
这就是所谓的:
public static void DestroyVB(PoolManagerVBObject PvbObject)
{
VBPool[--nextItemIndex] = PvbObject;
}