Freeing native buffer in MeshCollisionShape

Hi Everyone,

I’m currently optimizing the nio parts of my game. Is there a best practice to free the native buffer that a MeshCollisionShape creates? I create a lot of MeshCollisionShapes during the game and wouldn’t like to end up running out of native memory.

Well the best practice is to nto do anything, and let the garbagecollector free it.

The not suggested practice might be to call the finalize manually to force free the native part, and set the objectid to zero, so the normal finalize call will not do a double free.

I would like to add that as long as a memory leak is not happening every frame, it’s not THAT a big deal. It’s still better to clean the memory, but sometimes it’s only a source of bugs.

For exemple, a lot of gui libraries like SDL and opengl have memory leaks when you run even a simple program with valgrind (which can detect such memory leak). But, it’s not a big deal, cause theses leaks only happen while initialization.

An other exemple of the opposite (bad practice) is planetside 2, where you have a leak of about 1 meg by sec, leading to an inevitable crash after one hour of game on a 2 giga ram computer. This leak happen all the time, and it’s a problem because the user can see it, and is disturbed by it.

Also, remember what Michael A Jackson (not the singer) said

The First and Second Rules of Program Optimisation

1 - Don’t do it.
2 - (For experts only!): Don’t do it yet.

Only optimize when you actually need it.

@Empire Phoenix said: Well the best practice is to nto do anything, and let the garbagecollector free it.

I’d love to leave the task to the GC but you know how good that works with a 100 bytes object in Java’s heap that contains a 100MB object that is not under GC control: the GC won’t clear the object off the heap until it runs out of Java heap space - and that won’t happen before I run out of non-managed heap.

@Empire Phoenix said: The not suggested practice might be to call the finalize manually to force free the native part, and set the objectid to zero, so the normal finalize call will not do a double free.

I also thought about something like that. Funny fact: although I use norman’s native bullet implementation I don’t have the native MeshCollisionShape but rather the plain Java one that has no finalizer method. So I figured I could just free the bufferes themselves.

@bubuche said: Only optimize when you actually need it.

Yes - maybe I should check the nio heap more carefully and verify that I will definitly run out of non-managed memory before I start to optimize a thing that will never happen.

Thanks for both your suggestions! I will play around a bit and check if the optimization is really necessary.

The other thing, set the max heap to a reasonable while-still-GC-inducing size and set the direct heap to something huge.

Personally, I recommend leaving the regular heap at default (256m) and increasing the direct memory heap to 1 gig. Only increase regular max heap when absolutely necessary and then only as much as needed.

So often developers ramp up max heap to 1 gig without good reason and that really screws up direct buffer management. (Especially if it’s left at default.)

What might also work is a Simple System.gc() at least on the hotspots this triggers a full collection, wich also removes the few byte objects with 100mb buffer behind them.

Btw funny sidefact In fact meshcollisionshapes nearly use zero directmemory, as they directly allocate using low level internally, only the mesh send from jme is a directbytebuffer.

@pspeed said: The other thing, set the max heap to a reasonable while-still-GC-inducing size and set the direct heap to something huge.

Personally, I recommend leaving the regular heap at default (256m) and increasing the direct memory heap to 1 gig. Only increase regular max heap when absolutely necessary and then only as much as needed.

So often developers ramp up max heap to 1 gig without good reason and that really screws up direct buffer management. (Especially if it’s left at default.)

Thanks for the hint. I will try around with that - only problem is that I have the mesh’s data also on the java heap in an octree to be able to quickly add/remove blocks from it (yes it’s a voxel game) :wink:

@Empire Phoenix said: What might also work is a Simple System.gc() at least on the hotspots this triggers a full collection, wich also removes the few byte objects with 100mb buffer behind them.

Btw funny sidefact In fact meshcollisionshapes nearly use zero directmemory, as they directly allocate using low level internally, only the mesh send from jme is a directbytebuffer.

You are right - I overlooked that it is just a “normal” allocation and not a direct one here in Converter.convert():

[java]
//…
jBulletIndexedMesh.triangleIndexBase = ByteBuffer.allocate(mesh.getTriangleCount() * 3 * 4);
jBulletIndexedMesh.vertexBase = ByteBuffer.allocate(mesh.getVertexCount() * 3 * 4);
[/java]

Thanks - I guess that saves me a lot of afford then. Still I will play around with the memory settings - maybe I don’t need to free any direct buffers myself after all - that would be my favorable solution :slight_smile:

as you seem to use jbullet it is not using any direct at all.

The native one does just directbuffers, but they are only like 10% of the size, as the internal acceleration tree is purly done native by malloc