views:

74

answers:

2

I have a program that uses a lot of images. It loads alot of images from file, and stores them so they are only loaded once. It also creates multiple BufferedImages, about 400x400, there would be no more than 10 of these.

The images from file total around 6MB. Each BufferedImage should be approx 400x400x4=640KB.

Yet, the memory usage is 500MB!

Some of this will be for the rest of the program, but I'm pretty sure that the images are taking up most of the space.

Does anyone know what to do about this? Or an alternative to BufferedImage that uses less memory?

+1  A: 

Is your program a web application ? or you are developing a JRE-like application ? How do you load up your images ?

In a web-based application, I would use a CSS-Sprite image to solve my problem, because it cut off several HTTP requests and improve both bandwith usage and memory usage on load.

In a JRE application, there should be a way to use an image sprite in the same way, loading an offset of 400x400 of your image sprite to reduce usage of the BufferedImage object and improving performance.

LoganWolfer
It is a normal JRE program. The images that are loaded from file use Toolkit.getDefaultToolkit().createImage(imageName). The BufferedImages are created using the standard BufferedImage constructor. Not quite sure what you mean about the image sprite, do you have an example?
DanieL
You can check out for this website for the web-based version of a sprite technique : http://css-tricks.com/css-sprites/I still haven't found any way to implement such a technique in a JRE-based program, maybe the lead of Stephen C could be helpful.
LoganWolfer
+4  A: 

It sounds to me like your application (not the library) has a memory leak. In the first instance you should try to identify the leak using a standard Java memory profiler.

EDIT

Now you've identified that there are lots of BufferedImages hanging around, the next thing you need to do is figure out why they are still reachable. Take a heap dump, look at some instances and see how they are connected to a heap root; see http://download.oracle.com/javase/6/docs/technotes/guides/visualvm/heapdump.html

When doing this kind of stuff, it is useful to look at the relevant parts of the Java source code using your favorite Java IDE.

Stephen C
Steven, how does one use it? Any good links? Thanks.
Hamish Grubijan
Start with VisualVM http://download.oracle.com/javase/6/docs/technotes/guides/visualvm/profiler.html ... or look at the results of the Google search provided above in a comment.
Stephen C
Thanks! I didn't realise I had this on my machine the whole time... Well it looks like BufferedImages are the problem, I have 206 of them =O. But none of my objects have references to most of them! So they seem to stick around after I'm done with them...
DanieL
I've had a look at the heap dump and the only references to them are biimage, referent, bImg, bufImg, and things like that. None of that is part of my code. Any idea how to get rid of them?
DanieL
Examine the reference chains back to the heap roots. I'd be very surprised if at least one of the references in the chain is not being held in a class or instance variable of a non-JDK class. And even if that is the case, there's probably some JDK method that will break the chain at the root allowing everything to be GC'ed.
Stephen C
Just to make it clear, you just need to break the chains back to the GC roots ... somewhere ... and the objects become unreachable, and eligible for garbage collection.
Stephen C