Performance with very large object counts

I wrote a small set of utilities in JOGL that implement 2D PostScript rendering in 3D space, i.e. implemented most of the PostScript path and graphics state operators. So you can create a path and then stroke (including dash, joins, caps, etc.) and fills. Kind of fun. I think this my fourth PS implementation but definitely the first in Java. The resulting path can be rendered in 2D or extruded to make a filled shape. It works very nicely, but then I ran into a problem.

I wrote a simple temperature wave simulation that shows the variation of temperature with depth in the ground, both vertically and over time. Then I run the simulation. Problem is that it generates a LOT of objects, e.g. 300 data points at 10 depths results in 300x10*4 objects. At a modest 20 FPS, this generates 240,000 objects a second. It can run at 35 FPS initially, but after a little while it starts pausing and the rate drops to 10 FPS (QuadCore MacPro).

None of the cores are maxed, so my thought is that it is GC as the heap gets fragmented. I assume it is not GPU bound as I can’t see why it would be. I’ve done a little dumping of the GC data (gc:verbose) but that doesn’t seem to tell me much.

Thoughts? Comments? Am I missing something? I am no Java maven so that is entirely possible.

Well - what is the output of gc:verbose?

And at any rate: 250k objects a second is way too much garbage to create for smooth client operation; you’re going to start looking into object reuse and pooling to get that down to, say, 100th of the amount.

Cas :slight_smile:

I agree that 250k/s is way too much and I am looking at how to minimize that. That being said, I guess I may also have to learn more than I want about how the GC works in general. I was hoping that there might be an easier way, being the lazy person that I am - or at least I would prefer to spend my time on more interesting tasks than memory management in Java.

Also, some of it is not in my control as it is in the generation of the paths themselves, which are GeneralPaths. But I am looking at how I can avoid that as well.

If you want to learn more about GC, this is a good resource:
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

I doubt that you can tune any GC to efficiently handle 250k objects of garbage a second though, so you probably might want to introduce some pooling, or maybe you can apply the flyweight pattern somewhere to reduce garbage.

Thanks for the feedback. As is often the case, when I thought about it some more and turned the problem on its side, the right path (so to speak :wink: was apparent. I have written the pooling object to handle all the elements I need to manage. Now I need to retrofit the existing code to use the new constructs. One of the consequences is that I had to abandon using GeneralPath and use my own path object for everything, so I also had to write a Bezier flattener, but that’s no big deal - been there, done that. I had already written the rest of the Bezier support, anyway. But I learned some more about Java and GC, which is always good.