Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

wrldwzrd89

macrumors G5
Original poster
Jun 6, 2003
12,110
77
Solon, OH
Hey guys, I'm working on a cross-platform image editor, like MSPaint in complexity (but better, of course :p). Anyway, the reason I started this thread is because of a highly annoying limitation I've run into... when I attempt to specify an image size greater than 128x128 pixels, the program (which is written in Java 1.4) dies with an OutOfMemoryError. Sometimes it locks up instead, and produces multiple OutOfMemoryErrors before dying - it tends to do this if the image size is just slightly above the upper limit.

1) Is there any way to work around this?
2) If the only solutions are to change my programming methodology to use less RAM or increase the Java heap size, would I be better off changing languages - say, to Python?
 

lazydog

macrumors 6502a
Sep 3, 2005
709
6
Cramlington, UK
Have you tried increasing the heap size when you run your program?
128x128 pixels is pretty small though to be running out of memory.

b e n
 

wrldwzrd89

macrumors G5
Original poster
Jun 6, 2003
12,110
77
Solon, OH
Have you tried increasing the heap size when you run your program?
128x128 pixels is pretty small though to be running out of memory.

b e n
I have not tried this - I figured there was a way to do it from the command line but didn't know that that's how it is done.

That said, you are right - I wonder if my Java heap size is abnormally small. I thought the Java heap was 256 MB by default. Is there a way I can check it?
 

lazydog

macrumors 6502a
Sep 3, 2005
709
6
Cramlington, UK
I've just done a man java and it says that the maximum heap size is 64MBytes.

You could try increasing this value, eg to 256MBytes, like this

Code:
java -Xmx256m your_paint_program

The other way you could be running out of memory is by running out of stack space.

b e n
 

wrldwzrd89

macrumors G5
Original poster
Jun 6, 2003
12,110
77
Solon, OH
I've just done a man java and it says that the maximum heap size is 64MBytes.

You could try increasing this value, eg to 256MBytes, like this

Code:
java -Xmx256m your_paint_program
The other way you could be running out of memory is by running out of stack space.

b e n
Good to know, thanks! I doubt I'm running out of stack space, since I'm not making a whole lot of function calls, other than ones to the Java API. I suspect that the problem lies with the programming methodology I'm using, namely the image buffer being rather large.
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
It seems like there must be something really wrong w/ the way data structures are being stored in memory... off the cuff math leads me to:
128x128 pixels * 32-bit color depth = 64KB
Adding an 8-bit alpha channel, it's still only 80KB

This is, of course, in raw primitive types. Storing in capital-I Integer, or other container types would increase the overhead, but not by a factor of 1024.

Do you have a pixel class that stores all of the information? Are its fields primitive types? If not, how are you storing things? lazydog's tip on increasing the heap size is good, and should help, but before you try that I'd look at how things are laid out and try to correct that first. Maybe you're accidentally leaking references, and hence memory?

Maybe using a tool like this:
http://khelekore.org/jmp/

Or the debugger built in to an IDE (the NetBeans one seemed pretty good) could give you a hint on where to start looking for big objects that aren't going away.

Some other things that you may need to consider are undo history... i would only keep 1-2 copies in memory, and commit the rest of the undo history to disk. When undo is performed, you have to grab the most recent copy and restore it, then push a version from disk onto the end of the queue.

-Lee
 

wrldwzrd89

macrumors G5
Original poster
Jun 6, 2003
12,110
77
Solon, OH
It seems like there must be something really wrong w/ the way data structures are being stored in memory... off the cuff math leads me to:
128x128 pixels * 32-bit color depth = 64KB
Adding an 8-bit alpha channel, it's still only 80KB

This is, of course, in raw primitive types. Storing in capital-I Integer, or other container types would increase the overhead, but not by a factor of 1024.

Do you have a pixel class that stores all of the information? Are its fields primitive types? If not, how are you storing things? lazydog's tip on increasing the heap size is good, and should help, but before you try that I'd look at how things are laid out and try to correct that first. Maybe you're accidentally leaking references, and hence memory?

Maybe using a tool like this:
http://khelekore.org/jmp/

Or the debugger built in to an IDE (the NetBeans one seemed pretty good) could give you a hint on where to start looking for big objects that aren't going away.

Some other things that you may need to consider are undo history... i would only keep 1-2 copies in memory, and commit the rest of the undo history to disk. When undo is performed, you have to grab the most recent copy and restore it, then push a version from disk onto the end of the queue.

-Lee
Thanks. The program doesn't have Undo/Redo support implemented yet, so that's not the issue. I don't have any of that stuff - I'm using Java's built-in BufferedImage type for storing the image. I have 2 BufferedImages at all times - one fixed size (512x512) for the canvas, and one variable size for the preview. If using the approach you suggested - with a custom pixel class and image canvas - would help, I'd be more than willing to try it.
 

wrldwzrd89

macrumors G5
Original poster
Jun 6, 2003
12,110
77
Solon, OH
Finally got this fixed. Turns out I was using the wrong approach.

I was using a 2D JLabel array to handle the image grid, which is hugely wasteful. After I switched to a BufferedImage-based canvas the problem went away. :D
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.