为什么BufferedImages会增加程序运行时使用的ram数量?

时间:2016-08-28 20:13:12

标签: java memory bufferedimage

在Java中,由于使用了BufferedImage,我遇到了OutOfMemoryError。当我向控制台打印时,BufferedImage单独使用了多少内存(以字节为单位),我注意到他使用的字节数呈指数增长。我的结果如下:

.switch-container {
  width: 100px;
  display: inline-flex;
  flex-flow: column;
  align-items: center;
}

我使用以下代码生成结果:

    7396
    12996
    23104
    40804
    71824
    125316
    217156
    372100
    630436
    1060900
    1763584
    2903616
    4726276
    7595536
    12054784
    18887716
    29181604
    44435556
    66650896
    98446084
    143089444
    204547204
    -249500608
    -140383168

为什么这种增长如此之大,我怎样才能保持这种增长?此外,当数字前面有一个负号(最后2个)时,它是什么意思?

编辑:

请注意,宽度和高度不断变化,但我不希望它们增加(对不起)

1 个答案:

答案 0 :(得分:1)

当您创建BufferedImage TYPE_INT_ARGB(或任何TYPE_INT_*时),您正在创建一个int支持数组来保存您的像素,这正是{ {1}}很久。由于Java width * height是32位或4字节,因此该数组将使用int个字节。代码中的width * height * 4只是这个支持数组的一个薄包装器。

所以,你看到的增长是完全可以预期的。根据堆的大小,您将在某个时刻耗尽内存,尝试创建更大的DataBuffer

突然负值的原因只是表达式:

BufferedImage
buff.getSize() * DataBuffer.getDataTypeSize(buff.getDataType()) / 8 变得足够大时,

会产生integer overflow

作为Java语言中的buff.getSize()*运算符have equal precedence,表达式将从左到右进行计算,并且乘法将溢出,即使最终结果(之后)除以8)应该是有效的/。你可以通过添加一个括号来强制分裂首先发生它来修复它:

int

或者只使用buff.getSize() * (DataBuffer.getDataTypeSize(buff.getDataType()) / 8) s:

long