为什么 BufferedImage 需要超出其数据数组大小的这么多内存?

uck*_*man 5 java heap bufferedimage

我正在尝试确定任何给定的 TYPE_INT_ARGBBufferedImage将使用多少堆,以便对于进行一些图像处理的程序,我可以根据我们提供的图像大小设置合理的最大堆。

我编写了以下程序作为测试,然后我用它来确定它可以在没有 的情况下运行的最小最大堆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);
  }
}
Run Code Online (Sandbox Code Playgroud)

(印刷值的预期大小int[],其中所述BufferedImage的象素数据被存储。)我希望发现的是,所要求的最大堆是一样的东西x + c,其中x是所述数据阵列的大小和c是由一个恒定加载的类的大小、BufferedImage对象等。这是我发现的(所有值都以 MB 为单位):

4*w*h 最小最大堆
----- -----
  5 -
 10 15
 20 31
 40 61
 80 121
160 241

1.5x非常适合观察。(请注意,我没有发现 5MB 图像的最小值。)我不明白我看到了什么。这些额外的字节是什么?

uck*_*man 1

经过进一步调查,问题似乎是堆中的老一代无法充分扩展以容纳图像的数据数组,尽管堆中总体上有足够的可用内存。

有关如何扩展老一代的更多详细信息,请参阅此问题