简体   繁体   English

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

[英]Object pool seems to be returning an object copy rather than an object reference

I have written a simple object pool manager to dish out vertex buffers wrapped in a very simple class on demand. 我编写了一个简单的对象池管理器,以按需分配包装在非常简单的类中的顶点缓冲区。 Everything works OK except that it seems the objects being returned are being copied somehow rather than referenced, as memory use goes up unexpectedly. 一切正常,除了看起来似乎正在以某种方式复制返回的对象而不是引用,因为内存使用意外增加。 All the objects in the pool are instantiated at runtime in a bog standard list. 池中的所有对象都在运行时在沼泽标准列表中实例化。 This is the initializer code: 这是初始化代码:

 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));
        } 
    }

This is the Get Object method: 这是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++];
            }          
    }

And finally the code that uses the objects: 最后是使用对象的代码:

for (j = 0; j < limit; ++j)
{
   if (thisChunk.voxelVB.Count <= j)
   {   
       thisChunk.voxelVB.Add(VBPoolManager.GetVB());
   }

It seems like when GetVB() is called the returned object is having a copied made as ~260MB of RAM is eaten up. 似乎当调用GetVB()时,由于消耗了〜260MB的RAM,返回的对象正在复制。 This obviously should not happen as the objects are already created in the PoolManager. 显然这不会发生,因为对象已在PoolManager中创建。 If I replace the GetVB() call with just a new object() the memory consumption is the same, which is why I am led to believe the copy is being made. 如果我只用一个新的object()代替GetVB()调用,则内存消耗是相同的,这就是为什么我被引导认为正在制作副本。 Anyone got any ideas ? 任何人有任何想法吗?

This implementation will always leak memory. 此实现将始终泄漏内存。 You never remove references from the pool, and you never return objects to the pool. 您永远不会从池中删除引用,也永远不会将对象返回到池中。

A correctly implemented object pool would only hold references to available objects. 正确实现的对象池只能保存对可用对象的引用。 When an object is retrieved from the pool, it shouldn't be referenced by it anymore. 从池中检索对象时,该对象不应再被其引用。 This way the objects can be garbage collected in case they are not returned to the pool. 这样,可以在不将对象返回池中的情况下对其进行垃圾回收。 This points to another problem - you don't seem to have any way to return objects to the pool. 这指出了另一个问题-您似乎没有任何方法可以将对象返回到池中。

Also, your pool is not thread safe. 另外,您的池不是线程安全的。

If you want to see how to implement an object pool correctly, you can check the Roslyn ObjectPool 如果要查看如何正确实现对象池,可以检查Roslyn ObjectPool

This is the dispose method of pool manager code : 这是池管理器代码的dispose方法:

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

And this is what calls it : 这就是所谓的:

private static void ClearChunkVB(Vector2 PchunkXZ)
{
        VBContainer thisChunk;
        int j;

        thisChunk = Landscape.chunkVB[(int)PchunkXZ.X, (int)PchunkXZ.Y];

        if (thisChunk.voxelVB.Count > 0)
        {
            for (j = 0; j < thisChunk.voxelVB.Count; ++j)
            {
                thisChunk.voxelVB[j].VertCount = 0;
                VBPoolManager.DestroyVB(thisChunk.voxelVB[j]);
            }

            thisChunk.voxelVB.Clear();
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM