glDeleteBuffers Very Inconvenient.

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

glDeleteBuffers Very Inconvenient.

millerni456
Hello All,

I've run into an issue with Java OpenGL:
The issue is that if I want to delete any buffers that I generated (such as for VBO's), and I am required to have a handle to an OpenGL context.

But, in a game, if I constantly recreate these buffer, I will need to keep cleaning after myself (which unfortunately reveals the abstraction Java has).
Also, I need to be able to delete these buffers on a non-OpenGL thread.

I realize there are ways to get the OpenGL context on a thread that doesn't have one, but If I continually do this, wouldn't this create a major performance drop?

Anyways, I was really hoping there would be some way that Garbage Collection would delete these buffers, but that doesn't seem possible.

--Note: On a previous game I made, I preallocated say 1000 renderable objects that have buffers associated with them.  Then when terminating the game, I would then delete all of these buffers.
During game play I would reuse these preallocated objects so that I didn't ready into a OutOfMemoryError.
(This isn't very much a Java way to handle things, and although cumbersome, it was possible.)


I'm hoping very much that there is a solution/workaround that is feasible! :)
I greatly appreciate any feedback for discussion or advice you have to offer.

God bless!
-Nick.
Reply | Threaded
Open this post in threaded view
|

Re: glDeleteBuffers Very Inconvenient.

millerni456
Hey all,

I found an interesting article regarding Java's garbage collection.

It said this: "A finalizer in Java is the opposite of a constructor. While a constructor method performs initialization for an object, a finalizer method performs finalization for the object. Garbage collection automatically frees up the memory resources used by objects, but objects can hold other kinds of resources, such as open files and network connections. The garbage collector cannot free these resources for you, so you need to write a finalizer method for any object that needs to perform such tasks as closing files, terminating network connections, deleting temporary files, and so on."

URL: http://docstore.mik.ua/orelly/java-ent/jnut/ch03_03.htm

So I wonder if grabbing an instance in the finalize method would create a performance drop as I had worried about earlier.
If it does, at least I can still do what I did in my last game in a more abstract way!

Reply | Threaded
Open this post in threaded view
|

Re: glDeleteBuffers Very Inconvenient.

Sven Gothel
Administrator
On 01/23/2013 12:11 AM, millerni456 [via jogamp] wrote:

> Hey all,
>
> I found an interesting article regarding Java's garbage collection.
>
> It said this: "A finalizer in Java is the opposite of a constructor. While a
> constructor method performs initialization for an object, a finalizer method
> performs finalization for the object. Garbage collection automatically frees
> up the memory resources used by objects, but objects can hold other kinds of
> resources, such as open files and network connections. The garbage collector
> cannot free these resources for you, so you need to write a finalizer method
> for any object that needs to perform such tasks as closing files, terminating
> network connections, deleting temporary files, and so on."
>
> *URL: http://docstore.mik.ua/orelly/java-ent/jnut/ch03_03.htm*
>
The finalize method is not guaranteed to be called
and you have no control when it is called.
Hence utilizing this 'hook' to implement a controlled lifecycle for
an object is not at all suitable, hence we use an explicit 'destroy' method
(or similar naming) in our API(s).

> So I wonder if grabbing an instance in the finalize method would create a
> performance drop as I had worried about earlier.
> If it does, at least I can still do what I did in my last game in a more
> abstract way!

I don't know how this is related .. will read your prev. post.

~Sven



signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: glDeleteBuffers Very Inconvenient.

Sven Gothel
Administrator
In reply to this post by millerni456
On 01/22/2013 11:51 PM, millerni456 [via jogamp] wrote:
> Hello All,
>
> I've run into an issue with Java OpenGL:
> The issue is that if I want to delete any buffers that I generated (such as
> for VBO's), and I am required to have a handle to an OpenGL context.
>
Of course. and not only a handle to 'an' (-> any) OpenGL context,
but the handle to _the_ OpenGL context used to creat this object,
or a shared one!

> But, in a game, if I constantly recreate these buffer,
Why would anybody would do that ?
As w/ any API - dynamically creating objects on the fly is always
a performance hog and should never ever happen!
Better reuse buffers, cache or pool them .. don't waste performance
on resource management while doing your animation, whether it's Java,
OpenGL or whatever.

> I will need to keep
> cleaning after myself (which unfortunately reveals the abstraction Java has).
> Also, I need to be able to delete these buffers on a non-OpenGL thread.
By definition, an OpenGL thread is a thread which has an OpenGL context current.
There is no _the_ OpenGL thread.

>
> I realize there are ways to get the OpenGL context on a thread that doesn't
> have one, but If I continually do this, wouldn't this create a major
> performance drop?
Depends on implementation of OpenGL (i.e. Mesa3D is fast in switching context),
but in general it's indeed better to not switch the GLContext all the time.
Hence we now have the Exclusive Context Thread (ECT) feature:
  <http://jogamp.org/git/?p=jogl.git;a=commit;h=224fab1b2c71464826594740022fdcbe278867dc>
>

> Anyways, I was really hoping there would be some way that Garbage Collection
> would delete these buffers, but that doesn't seem possible.

And it is not desired at all -> see my reply to your follow-up post.

Using and relying on GC (and/or temporary objects) in a high performance workflow
is just the wrong design.
A lesson to be learned from embedded, RT and security critical development,
where resources are scarce and no time shall be wasted by ioctl kernel calls
like memory allocation. Note: A Java NIO memory allocation is almost equal
to a kernel memory mapping within PAGESIZE -> costly!

Well, if you use the GLEventListener model, you can use dispose(..)
to release all your GLContext resources.

If you don't .. you need to add a hook to the GLAutoDrawable implementation
(override .. or whatever) to receive the 'about-to-be-destroyed' windowing system
message to issue proper cleanup while your GLContext is current.
The latter should be performed with a programmatic exit as well.
Again: All this is ensured if you use GLEventListener ..

Hope this helps.

~Sven


signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: glDeleteBuffers Very Inconvenient.

gouessej
Administrator
In reply to this post by millerni456
Hi

Garbage collection is not working very well with Java objects bound to "native" objects because they are allocated on different heaps. The garbage collection is only sollicited when there is not enough memory on the Java heap, not on the native heap. It is common to manually handle this kind of resources. You can release the native resources used by a direct NIO buffer so that you don't run out of memory. Object pooling is only efficient on objects that are very expensive to destroy in desktop environments but still very efficient on Android DVM because of its poor garbage collection.

There is no obvious solution in JOGL, Sven should just check that we don't keep any reference on unused NIO buffers. I will post a link to an extract of an article I wrote about memory management in a few hours, it might help you a bit.

You can queue some runnables in order to destroy OpenGL resources step by step, there are some solutions but their places are rather in middle level and high level APIs.

N.B: direct NIO buffers are no more page aligned in Java 1.7 by default.
Julien Gouesse | Personal blog | Website