Memory Leak

Hey guys… I think I've found a major memory leak in jme physics.



There doesn't seem to be a good way to delete Geom's from an Ode World, because Ode Body's are only deleted from the world when their physics node finalizes - which won't happen because physics nodes are refered to (indirectly) by those ODE bodies, and the ODE bodies are themselves all stored in the list World.bodyList.



There is a circular reference here, and since World is kept alive, and it refers to a member of the circle… finalize is never called.



Now, one could delete each Body manually from the world… but theres no easy way to do this through the jmePhysics API.



The path to GC Root that is tying this up is:

DynamicPhysicsNode>OdeBox>GeomTransform>Body>World

Possible partial solution:



in OdePhysicsSpace.delete(), clear the whole list of bodies in world.



But this still doesn't allow you to delete an individual physics node or collision geometry from the space - you can just clear the entire physics space all at once.

I did not understand it entirely. Why is deleting a DPN not enough? It should remove the body from the world as well.

Perhaps I misunderstood? I was looking at the code, and the only thing that calls World.deleteBody is the DynamicNode finalization method.



The problem is that the World has an indirect reference to each dynamic physics node, so they are never garbage collected, and finalization is never called.



Or did you mean that there is an explicit dynamic physics node delete method?

I have removed the list of Bodies in World. Does this fix the the leak?

Hmm… be careful Irrisor. That should fix the leak, but I've been playing around with various solutions to these memory leaks for a bit now, and I've noticed some strange happenings. In my program, I create large numbers of physcis objects at a time, run them for a while, then I have to clear them out and replace them with a new set. I do this repeatedly, which is why the memory leaks are such a big issue for me.



So I do have the leaks under control, by modifying OdePhysicsSpace.delete() to clear the body list in World, and also by having it clear-out and replace  the various Collision, Contact, and ReusableContactInfo objects that OdePhysicsSpace keeps hanging around. (Code at the bottom of this post).



However, I think this might have exposed some bugs… I'm still trying to track down the source of this. After running physics a few times there seems to be a small chance that Ode will throw an error saying it can't a Body.



Do you know of any reason that Ode might refer to Geoms or Bodies after they are deleted?


    public void delete() {
        removeAllFromUpdateCallbacks();
        removeAllObjects();
        removeAllJoints();
        this.appliedContacts = 0;
        world.clear();       
        collision = new JavaCollision( world );
        odeContact = new Contact( collision.getContactLongBuffer(), collision.getContactFloatBuffer() );
  
        usedContactInfo = null;
        lastUsedContactInfo=null;
        availableContactInfo= null;

       usedContactInfo2= null;
       lastUsedContactInfo2 = null;
       availableContactInfo2 = null;
    }




Specifically, the bug I've been encountering is this one:

Geom with native address 0x3bd57fd73f1e45d9 not found!

(the address is just an example).

It's throw by the getGeomFromNativeAddr of Geom, in the IterateContacts method of OdePhysicsSpace.

After that, ode throws an error and crashes.

Its worth noting that I am not sure that fixing the memory leak causes this problem. Its just that I only noticed it happening around the time I fixed the leak.

Actually, I've been investigating this further today, and that particular error arises with our without the memory leak fix.

It's possible that fixing the leak caused the error. You would have to check where this address comes from to track that down.