VBO's and GC

Hi all,
I didn’t know where to post this, but since im using LWJGL…i might as well post it here.
I can see a serious memory leak regarding VBOs and the GC. When a Geometry class gets isolated and hence GC’ed, and that geometry class is tied with VBO’s (i.e. has a VBO id), the required calls to free up the VBO and delete the buffer from VRAM/wherever else wont be called and the VBO id will be lost for ever…Hence, on a lot of scene switching, on alot of the scenegraphs out there, with VBO’s enabled…the memory goes up, the fps goes down because the driver may not change new VBO’s for old ones and move the new ones in system ram hence on every render call, the gfx has to fetch the data through the system bus in the system ram. And the same problem applies to Texture id’s too…

So my question is, does anyone know of a reliable way to delete the VBO’s when the Geometry class gets GC’ed? Are finalisers good enough to do this? From my understanding…they arent

Why are VBOs more of a problem than any other allocated resouce (GL texture objects for instance)?

Also, why do you say that the finalizer is not a good solution? I’m just curious.

Being a C++ coder by day, I tend to write code to manage pretty much everything I create (Don’t laugh :)), but I can see why just putting the cleanup in finalize() would be useful.

They arent, i just used VBO’s as an example…

[quote]Also, why do you say that the finalizer is not a good solution? I’m just curious.
[/quote]
Its my understanding that they might not be called on all JVM’s. I am targetting 1.5, not sure if the finalisers situation has improved in that…

If finalize doesnt get called in >1.5, or if a new cleanup method hasn’t been created, then this is a very serious bug in game programming with an OGL pipeling using java…

This is not what happens. The old ones is moved to system ram and the new ones is uploaded to the gfx card. The opengl driver does this behind the scenes. That is why some games uploads all the texture at startup. The driver manages what needs to be in system and gfxcard memory. All the game have to do is make sure all the textures will fit in system ram, and that it don’t use more than the gfx card can hold from frame to frame.

Ofcourse, you will run out of system ram eventually if you have a memroy leak.

It is the programmers job to make sure there is no memory leak. It is a bug on your part if you loos all references to an object containing the texture/vbo id. One solution would be to delete the id when the object is removed from the graph. I’m sure it’s more complicated than that, but it has to be dealt with. Using the finalizer is one lazy way of dealing with it. It will work but there are a couple of traps. First it may take a long time before it is called depending on the gc. Also your relying on the java heap gc to delete system resources wich is not good. Finally you can not call opengl from the finalizer thread. The finalizer have to tell the gl thread to delete.

In the end you just have to make sure you clean up your own mess.

That depends on how good the driver is…

Thats one poor way of doing it. Its also as slow as a donkey without a carrot and it will probably cause a pause when the new VBO’s are created. (I am buffering the deleted VBO’s, but if there arent any available that are readily available, then creation is the only way…)

Yes, i know, but at least this guarantees when the object is collected, its resources are freed, If the user makes a mistake and hasn’t kept the reference so its resources are freed from our managers…but I suppose that is their fault.

I’ve not come across any better way than the finalizer to do precisely this yet (for all native resources). Unfortunately the finalizer executes in the wrong thread as well, so it’s even more fiddly as you have to create a destruction callback runnable in some GL “event queue” and process any you find in there in your main thread every frame.

The other problem is that the GC has no idea of exactly how much native resource you’re actually wasting so objects tend not to get GCed until it’s waaaay too late. A GLTexture object might only take up 128 bytes in the Java heap but point to an 8MB texture on the card. Chances are it won’t get collected for a long, long time as the heap just won’t fill up.

I have been looking into ReferenceQueues to deal with the problem but I’ve not cracked it yet.

Cas :slight_smile:

References only get cleaned up and put into ReferenceQueues during garbage collection, the same as finalizers. But with references you don’t have access to the object any more, so it’s even more difficult than with finalizers.

That’s why I’ve stopped that line of enquiry :stuck_out_tongue:

What I actually need to write is… a complete GC of my own to take care of native resources. Yikes!

Cas :slight_smile:

Isn’t this the same issue that lead to the Java 2D disposer thread that was mentioned recently in that GC thread? How did they do it ?

They did it in completely the wrong way, that’s how they did it, and caused much grief. What is needed is a pure Java GC algorithm that can be plugged in to any kind of resource. That’d be nice. So you could effectively set up a few collectors to collect different kinds of things in different ways, give 'em some threads, and let them loose.

Cas :slight_smile:

Interesting, I wonder if something could be done with annotations to mark classes as “belonging” to a particular collector. You would proably need to manage separate heaps for each plugable collector or something, but it is an interesting idea.

I’d just like a pure Java GC with a fairly simple collector which I can manage my own objects in. Not, take note, Java heap objects, which the Java heap GCs already handle perfectly well. I would just like to be able to manage the invisible native bit separately using some nice tried-and-tested GC algorithim. Because such objects are created and destroyed far, far, far more slowly than Java objects this GC doesn’t need to be remotely clever or even particularly fast.

Cas :slight_smile: