I’m trying to find a may to minimize memory allocation and garbage collection in a Java OpenGL (JOGL) application. I am porting some C/C++/C# OpenGL projects to Java as a learning exercise. One thing I am running into is the lack of pointers in Java and the allocation of objects and GC of them as the application runs. In C/C++/C# I get the applications up and running without allocating additional memory or objects at runtime after startup by passing references around but in Java it seems my designs are incompatible.
As these designs have evolved they are using higher level objects. In C they were structs for Vectors and Matrices and others and in C++/C# classes. These all essentially boil down to arrays of bytes in memory and binary files stored to disk read into memory and mapped. Which are then cast in one way or another to float[] for OpenGL calls or object arrays internally within the application so I can us object based operations like operator overloading, add and multiply, or property accessing for example. This way I allocate everything on load and simply pass the data around. Java has thrown me for some loops. It appears I cannot cast data back and forth thus I keep creating lots of data and the GC comes by and does it work. This is noticeable by resources being consumed and cleaned up and a noticeable stutter during the application run. I have alleviated some of this by creating FloatBuffers in addition to VectorXf arrays for my geometry data and pass the FloatBuffer down to OpenGL. But when I need to update Vector data I have to recopy the data back to the float buffer. This also means I am storing double the data and incurring the overhead of the floatbuffer fills. VBO are a little differnet with static data as the data is sent once to the hardware but I sitll have to do the FloatBuffer allocation/copy logic. I’d like to hear how others are dealing with these issues. I’d like to keep the higher order objects for the functionality built in but be able to pass the data to OpenGL. Are my designs simply incompatible with Java? Do I need to move to FloatBuffers exclusively? How does one pass component data into a higher order object without the penalty of object creation. So many OpenGL applications exist that I suspect there is some ‘magic’ to utilize either the same buffer for float[] and Object[] or allocate contiguous block for object data and pass a reference to OpenGL. Any insight is greatly appreciated. |
Administrator
|
Hi
Never pass arrays or indirect NIO buffers to JOGL OpenGL methods or they will be converted into direct NIO buffers anyway. Object pooling is useless since Java 1.4 but you can use mutable objects to avoid creating tons of garbage. Track direct NIO buffers. Release their native memory manually when you don't need them anymore. It's up to you to take care of the native heap, not the Java heap. If you don't do that, you'll run out of native memory. No you can use dynamic VBOs too, which is what I do when animating models (key frames). When I switched to Java + JOGL in 2006, my blueprint became about 5% faster than the original one in C++. There is no magic, just look at all engines supporting JOGL, mainly Ardor3D (it has a build-in math library).
Julien Gouesse | Personal blog | Website
|
Free forum by Nabble | Edit this page |