对象池似乎返回对象副本而不是对象引用

时间:2015-11-18 23:06:00

标签: c# xna

我编写了一个简单的对象池管理器,用于根据需要将包含在非常简单的类中的顶点缓冲区分开。一切正常,除了看起来被返回的对象被某种方式复制而不是被引用,因为内存使用意外地上升。池中的所有对象都在运行时在沼泽标准列表中实例化。这是初始化代码:

 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()调用()内存消耗是相同的,这就是为什么我被引导相信正在制作副本。有人有任何想法吗?

2 个答案:

答案 0 :(得分:0)

此实现将始终泄漏内存。您永远不会从池中删除引用,也永远不会将对象返回池中。

正确实现的对象池只能保存对可用对象的引用。从池中检索对象时,不应该再引用它。这样,对象可以被垃圾收集,以防它们没有返回池中。这指向另一个问题 - 您似乎没有办法将对象返回池中。

此外,您的池不是线程安全的。

如果您想了解如何正确实现对象池,可以查看Roslyn ObjectPool

答案 1 :(得分:0)

这是池管理器代码的dispose方法:

update_time

这就是所谓的:

 public static void DestroyVB(PoolManagerVBObject PvbObject)
    {
         VBPool[--nextItemIndex] = PvbObject;
    }