Memory Issue

Topics: User Forum
Apr 3, 2011 at 6:41 PM

Hello everybody

We are building a PC and Xbox 360 game using farseer 2.1.3 and XNA.
Everything works very well and I am most impressd by the engine.

But we have one problem regarding memory and preformance.
Our problem is that the engine seems to keep information in the memory instead of releasing it when we clear it, clear its lists and remove all geoms and bodies manualy.

Using the ANTS Memory and preformance profilers we found that the problem is in

FarseerGames.FarseerPhysics.Collisions.Contact[]

FarseerGames.FarseerPhysics.Dynamics.arbiter[]  - 174 Instances >
FarseerGames.FarseerPhysics..Dynamics.Arbiter - 22272 Instance >
FarseerGames.FarseerPhysics.Collisions.ContactList - 66816 Instances > 
FarseerGames.FarseerPhysics.Collisions.Contact[] - 49.19MB

 

simulator = new PhysicsSimulator(new Vector2(0, 600));

The memory usage only increases when we load our level and not while we are playing and it does not decreas when we try to unload.

void UnloadAll()
        {
            simulator.Clear();

            Content.Unload();

            gameObjectList.Clear();
            imageObjectList.Clear();
            hudObjectList.Clear();
            motorObjectList.Clear();
            shotObjectList.Clear();
            laserObjectList.Clear();
            enemyObjectList.Clear();
        }

The level contains 174 objects, these objects are created by the texture to polygon ability and all in all its about 3150 vertices in the level.
Our creation of the objects is done the following way:

We read the level from xml and add the objects to a list, gameObjectList.

e.gameObjectList.Add(new GameObject());
e.gameObjectList[e.gameObjectList.Count - 1].textureName = tempTextureName;
e.gameObjectList[e.gameObjectList.Count - 1].layer = tempLayer;
e.gameObjectList[e.gameObjectList.Count - 1].position = new Vector2(tempX, tempY);
e.gameObjectList[e.gameObjectList.Count - 1].farseerShape = "custom";
e.gameObjectList[e.gameObjectList.Count - 1].LoadContent(e.spriteBatch, tempTexture, simulator, tempWeight);

 

 

LoadContent(....)
{
	    uint[] data = new uint[this.texture.Width * this.texture.Height];

            this.texture.GetData(data);

            Vertices verts = Vertices.CreatePolygon(data, this.texture.Width, this.texture.Height);
            verts = Vertices.Simplify(verts);
            vertCount = verts.Count;

            Vector2 farseerOrigin = verts.GetCentroid();
            this.origin = farseerOrigin;

            body = BodyFactory.Instance.CreatePolygonBody(simulatorInput, verts, mass);
            body.Position = position;
            body.IsStatic = false;
            body.Rotation = rotation;

            geom = GeomFactory.Instance.CreatePolygonGeom(simulatorInput, body, verts, 0);

            geom.FrictionCoefficient = 1.0f;
            geom.RestitutionCoefficient = 0f;

}

 

 

then we add the objects to the physics engine with

 

simulator.Add(gameObjectList[i].body);
simulator.Add(gameObjectList[i].geom);

 

that is all we do when loading them.

In the update() function of the XNA engine we update the collision bool of the objects with:

 

gameObjectList[i].update();

public void update() {              
	geom.OnSeparation = OnSeperation;                
	geom.OnCollision = OnCollision;
}

 

 

public List<Geom> cache = new List<Geom>();

private bool OnCollision(Geom geom1, Geom geom2, ContactList contactList)
        {
            collides = true;
            if (!cache.Contains(geom2))
            {
                cache.Add(geom2);
            }

            return true;
        }

        private void OnSeperation(Geom geom1, Geom geom2)
        {
            if (cache.Contains(geom2))
            {
                cache.Remove(geom2);
                if (cache.Count == 0)
                {
                    collides = false;
                }
            }
        }

 

in OnCollision() and OnSeparation() we just check if the objects are already colliding and add or remove them from the list of object colliding.
If colliding we set a bool = true;

But this should not be the problem because the memory only increases when loading a level and not when we update the collision bool.

Could anyone help us on how to solve this problem?
How can we unload the physics engine completely and reset it? 


 

 

 

Coordinator
Apr 5, 2011 at 11:27 PM

The 2.x engine contains a pool of objects that it keeps in memory - just will have to create a new PhysicsSimulator instance or clear the pool.