"java.lang.OutOfMemoryError: Java heap space" in image and array storage
I am currently working on an image processin开发者_运维技巧g demonstration in java (Applet).
I am running into the problem where my arrays are too large and I am getting the "java.lang.OutOfMemoryError: Java heap space" error.
The algorithm I run creates an NxD float array where: N is the number of pixel in the image and D is the coordinates of each pixel plus the colorspace components of each pixel (usually 1 for grayscale or 3 for RGB). For each iteration of the algorithm it creates one of these NxD float arrays and stores it for later use in a vector, so that the user of the applet may look at the individual steps.
My client wants the program to be able to load a 500x500 RGB image and run as the upper bound. There are about 12 to 20 iterations per run so that means I need to be able to store a 12x500x500x5 float in some fashion.
Is there a way to process all of this data and, if possible, how?
Example of the issue: I am loading a 512 by 512 Grayscale image and even before the first iteration completes I run out of heap space. The line it points me to is:
Y.add(new float[N][D])
where Y is a Vector and N and D are described as above. This is the second instance of the code using that line.
EDIT: The upper bound, as I mentioned but forgot to correct should be around: 20+ x500x500x5 (20 iterations, 500 width, 500 height, 5 dimensions (where 3 comes from RGB and 2 for the coordinates (The coordinates move and so do the pixels, so I need to record the values, which can and are decimals)) (Approx. 100000000 bytes)
I don't think you are going to be able to do this as an Applet. (There may be settings in the browser for how much memory to assign to applets, but I'm not aware of any.)
If you can use Java webstart, I would use that. You can set the amount of memory required:
<j2se version="1.4+" initial-heap-size="100M" max-heap-size="200M"/>
The advantage with using webstart is that the user does not need to configure their browser.
EDIT: The Java control panel does have memory settings for applets. See How can I start an Java applet with more memory?
However, unless you have just a handful of clients who don't mind altering their java settings (and that they have appropriate permissions and skills), this is not a nice user experience. With web start,you can set all this up in the JNLP descriptor and you're all set to go.
Have you tried increasing the initial heap size, as well as setting the maximum heap size?
java -Xms<initial heap size> -Xmx<maximum heap size>
e.g.
java -Xms256M -Xmx512M
The defaults are pretty conservative, and small so you definitely want to try and play around with your heap size settings.
To increase the heap space size beyond the default 64MB, you need to execute the application with -Xmx parameter (for the applet add it in the Java Runtime Settings which you can find in the administration tools on any OS). I guess though it's not an option in case this is gonna be a web application where you'll have to modify a lot of end-user machines. I'd like to find out more about that storage in an x-dimensional array. What exactly do you store? Why 4-byte floats? The uncompressed raw image is usually stored in an WIDTHxHEIGHT array where each cell contains a color object (e.g. 3 shorts describing RGB space). Such an array for a 500x500 image would require 500 * 500 * 3 (the amount of color dimensions) * 2(bytes for a short) = 1 500 000 bytes, way less than 500 * 500 * 5 (still haven't figured out why 5, probably you store color + coordinates) * 4 (bytes in float) = 5 000 000 bytes. Have in mind that exactly for this reason compression algorithms (like JPEG) have been developed, so that you don't have to keep in memory 1.5MB for each image. As of the iterations, but mostly for consequent storage of those, there's not much to say, unless you want to get into the hassle to write something like MPEG format where you'll have to only save the changes between frames.
1) 12x500x500x5 floats means about 60 MB, plus some overhead. You should have no problem reserving all that memory space on a reasonable machine, if you configure your JVM heap correctly (-Xmx500M for example). If on the other hand you run this as an applet, you should do some settings (I found this link for example, relevant for Java 6 update 10 and above).
2) You didn't provide much information regarding the data format per pixel. Maybe you can make it more compact. Why do you need 5 floats per pixel? You can store an RGB value as 3 bytes, and it seems you don't need to store the pixel location, since the position in the 2dimensional array already indicates the position.
精彩评论