Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a BufferedImage require so much memory beyond the size of its data array?

I'm trying to determine how much heap any given TYPE_INT_ARGB BufferedImage will use so that, for a program which is doing some image processing, I can set a reasonable max heap based on the size of image we feed it.

I wrote the following program as a test, which I then used to determine the least maximum heap under which it would run without an OutOfMemoryError:

import java.awt.image.BufferedImage;

public class Test {
  public static void main(String[] args) {
    final int w = Integer.parseInt(args[0]);
    final int h = Integer.parseInt(args[1]);

    final BufferedImage img =
      new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

    System.out.println((4*w*h) >> 20);
  }
}

(The printed value is the expected size of the int[] in which the BufferedImage's pixel data is stored.) What I expected to find was that the required max heap is something like x + c, where x is the size of the data array and c is a constant consisting of the sizes of the classes which are loaded, the BufferedImage object, etc. This is what I found instead (all values are in MB):

4*w*h   min max heap
-----   ------------
  5          -
 10         15
 20         31
 40         61
 80        121
160        241

1.5x is a good fit for the observations. (Note that I found no minimum for the 5MB image.) I don't understand what I'm seeing. What are these extra bytes?

like image 664
uckelman Avatar asked Oct 04 '10 10:10

uckelman


People also ask

What is the difference between BufferedImage and image?

List, the difference between Image and BufferedImage is the same as the difference between List and LinkedList. Image is a generic concept and BufferedImage is the concrete implementation of the generic concept; kind of like BMW is a make of a Car. Show activity on this post. Image is an abstract class.

How do I find the size of a BufferedImage?

Before you load the image file as a BufferedImage make a reference to the image file via the File object. File imgObj = new File("your Image file path"); int imgLength = (int) imgObj. length(); imgLength would be your approximate image size though it my vary after resizing and then any operations you perform on it.

What does ImageIO write do?

ImageIO can write multiple images, image metadata, and determine quality vs.

What are buffered images?

A BufferedImage is comprised of a ColorModel and a Raster of image data. The number and types of bands in the SampleModel of the Raster must match the number and types required by the ColorModel to represent its color and alpha components. All BufferedImage objects have an upper left corner coordinate of (0, 0).


1 Answers

There seem to be a bug in Oracle's VM introduced somewhere between 1.6.0_16 and 1.6.0_20. You can even reduce the problem to allocating an int array, as the problem is not only related to BufferedImage.

With 1.6.0_16, I need at least 413 MB heap to allocate an int array with 100,000,000 elements, which seem reasonable. With 1.6.0_20, the same operation requires at least 573 MB heap space, although only appr 400,000,000 bytes are actually used after allocating the array.

like image 115
jarnbjo Avatar answered Oct 13 '22 01:10

jarnbjo