setClip() and drawImage() tendency to leak memory.

Hi everyone,

I have run my latest game thru a profiler, and there is only one major leak of memory:

When I use g.setClip() and then g.drawImage( myImage ). The jvm create another image (from myImage), and then draw it, thus leaking a lots of int[], Rectangle, BufferedImage and WeakReference objects.
25 times per second and you got a few mb wasted.

I am not very familiar with the image producer/consumer technique, but I think it should be possible to have a special type of Image than just skip the pixels not to draw when clipped.

Can anyone (maybe chris?) help me out on this one?

Thanks,

Seb

This isn’t really a leak is it?

If you hit the Garbage Collect buttoin on tyour profielr do they go away?

If so then ist not a memory leak, or even an object leak.

Nonetheless for maximal performance the over-collection of objects can still be an issue. There’s been a lot of discussion on the old broads abotu strategies to minimize that, some of the gusy here may have specific suggestions for your specific case if they’ve run ionto something similar.

Okay, wrong word :slight_smile:

I hope someone have figured something out.
Since the java memory heap (at least under windows) tend to grow when you reach a certain size… it really an issue for me.

Thanks,

Seb

Indeed, for some operations Java2D does create an intermediate buffer.

Which jdk are you using? I’m guessing, it’s 1.4.1 as we’ve changed the way we dispose images to use WeakReferences instead of finalizers, which improved the situation a lot (just try the same test on 1.4.0), but we didn’t eliminate the problem completely.

Can you describe the problem a bit more? What’s the size of the images being created? Are you seeing a lot of garbage collection (run the app with -verbose:gc), is it affecting your framerate (increase the default amount of heap to see if it helps)?

The images would accumulate in the young generation until it’s full, and then the partial GC should clean it up, so unless it kicks in too often, it shouldn’t affect you much.

The best solution, of course, would be to avoid operations which use intermediate image if possible, or at least, limit the amount (use cache, for example, so you won’t have to re-render something on each frame).

[quote]Indeed, for some operations Java2D does create an intermediate buffer.

Can you describe the problem a bit more? What’s the size of the images being created? Are you seeing a lot of garbage collection (run the app with -verbose:gc), is it affecting your framerate (increase the default amount of heap to see if it helps)?

The best solution, of course, would be to avoid operations which use intermediate image if possible, or at least, limit the amount (use cache, for example, so you won’t have to re-render something on each frame).
[/quote]
Hi again,

Here is a better description of the situation:

I’m using a cauldron image (for an halloween game).
I have 2 differents images: one with the cauldron filled, and another with the cauldron empty.
While playing the game you fill the cauldron, there I use a setClip method to display only a part of the filled cauldron over the empty cauldron.

Since I need pixel precision I definitly can’t render 200 differents images of the cauldron.

I guess there is a way to create a extended version of Image object on wich I could set a percentage (like setFill( 0.5f ) and the image will just display the rows I need without recreating a whole new image.

To do this I believe I need to work with the image consumer/producer technics, wich I’m not familiar with… :frowning:

This is why I need some help :slight_smile:

(and btw, to answer your question, the gc kick often enough to regulary increase the java heap size significantly).

The game need to be an applet at the end (1.1) so I can’t use anything fancy.

Thanks for your time.

Seb

Just to clarify: which vm are you going to use? You won’t be able to use Java2D apis on 1.1.x vm, since Java2D was untroduced only in Java2 (1.2).

This I know.
I’m using 1.4.1 jdk for developpement purpose, but I use JVM 1.1 for production (explorer).
I restrict myself to the 1.1 api (as a lots of online game developper I believe).
I do not remember the image consumer/producer technique beeing Java2D specific.
I know you’re quite good at the latest Java2D stuff, but I imagine you’re also familiar with the old stuff too.

Thanks for your time,

Seb

Hey Fraggle, you can cache that cauldron.
Draw the cauldrons on top of each other into a BufferedImage and blit that to the backbuffer/screen instead. Only when the level in the cauldron changes do you need to redraw the cauldrons in the BufferedImage again. As your cauldron level probably changes very infrequently compared to frame updates you’ll be saving megs and megs of garbage every second.

You could even do it into a VolatileImage but my experience with this is nonexistent so I don’t know if it’s the best way.

Also consider specifying some different memory parameters for the VM with -Xms, -Xmx, and so on. -Xconcgc and -Xincgc seems to be pretty good at keeping spurious garbage from becoming a major problem.

Cas :slight_smile: