Possible Memory Leak with JOGL using VBOs
We are currently developing an application which visualizes huge vector fields (> 250'000) on a sphere/plane in 4D. To speed up the process we are using VBOs for the vertices, normals and colors. To prepare the data before sending d开发者_运维知识库own to the GPU we are using Buffers (FloatBuffer, ByteBuffer, etc..).
Some data to the cylinders: Each cylinder uses 16 * 9 + 16 * 3 = 192 floats -> 192 * 4 Bytes = 768 bytes.
After sending down the vertices we are doing the following cleanup:
// clear all buffers
vertexBufferShell.clear();
indexBufferShell.clear();
vertexBufferShell = null;
indexBufferShell = null;
We have monitored it with JConsole and we found out that the GarbageCollector is not run "correctly". Even if we switch down the cylinder count, the memory does not get freed up. In the JConsole Monitoring Tool there is a button to Run the GC and if we do that manually it frees up the memory (If we have loaded a huge amount of cylinders and decrease it a lot, sometimes over 600mb gets cleaned by the GC).
Here an image of the JConsole:
Now the question is how can we clean up this Buffers by ourself in the code? Calling the clear method and set the reference to null is not enough. We have also tried to call System.gc() but with no effect. Do you have any idea?
There is any number of reason the memory usage could increase. I would say its not a memory leak unless the memory increases every time you perform this operation. If it only occurs the first time, it may be that this library needs some memory to load.
I suggest you take a heap dump or at least jmap -histo:live
before and after to see where the memory increase is.
If you use a memory profiler like VisualVM or YourKit it will show you where and why memory is being retained.
Its not really a memory leak if the gc is able to clean it up. It might be a waste of memory, but your app seems to be configured to allow it to use over 800MB of heap. This is a trade-off between garbage collection performance and memory usage. You could also try to simply run your application with a smaller heap size.
There might not be a memory leak, but objects going to the Ternured
(area where the objects that passed alive in a minor gc goes).
These big step you see might be the Young Eden
that is full and after a minor gc is moving alive objects to Ternure
.
You can also try to tune up the garbage collector and the memory.
you might have plenty middle length live objects that are constantly passing to the Ternured
releasing them in full gc. If you dimension them well those objects go minor gc.
There are plenty jvm arguments to do this.
A good place to look at is here.
This one is suitable for you:
-XX:NewSize=2.125m
Default size of new generation (in bytes)
[5.0 and newer: 64 bit VMs are scaled 30% larger; x86: 1m; x86, 5.0 and older: 640k]
Regards.
The JVM will not free any objects until it has to (e.g.-Xmx reached). Thats one of the main concepts behind all GCs which you can find in the current JVM. They are all optimised for throughput, even the concurrent one. I see nothing unusual on the GC graph.
It would be a leak if the used heap after a full GC would constantly grow over time - if it doesn't -> all good.
in short: foo=null; will not release the object only the reference. The GC can free the memory whenever it likes to.
also: buffer.clear() does not clear the buffer, it sets pos=0 and limit=capacity - thats all. Please refer to the javadoc for more info.
VisualVM +1
have fun :)
(offtopic: if the buffers are large and static you should allocate them in the permgen. Buffers.newDirectFloatBuffer() would be one of those utility methods in latest gluegen-rt)
精彩评论