Java 为什么BuffereImage会增加程序运行时使用的ram数量?
在Java中,由于使用了BuffereImage,我遇到了OutOfMemoryError。当我将BuffereImage单独使用的内存量(以字节为单位)打印到控制台时,我注意到正在使用的字节数呈指数增长。我的结果如下:Java 为什么BuffereImage会增加程序运行时使用的ram数量?,java,memory,bufferedimage,Java,Memory,Bufferedimage,在Java中,由于使用了BuffereImage,我遇到了OutOfMemoryError。当我将BuffereImage单独使用的内存量(以字节为单位)打印到控制台时,我注意到正在使用的字节数呈指数增长。我的结果如下: 7396 12996 23104 40804 71824 125316 217156 372100 630436 1060900 1763584 2903616 472627
7396
12996
23104
40804
71824
125316
217156
372100
630436
1060900
1763584
2903616
4726276
7595536
12054784
18887716
29181604
44435556
66650896
98446084
143089444
204547204
-249500608
-140383168
我使用以下代码生成结果:
while (true) {
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
DataBuffer buff = img.getRaster().getDataBuffer();
System.out.println(buff.getSize() * DataBuffer.getDataTypeSize(buff.getDataType()) / 8);
}
为什么这一增长如此之大?我如何才能阻止这一增长的发生?另外,当数字前面有负号(最后2个)时,这意味着什么
编辑:
请注意,宽度和高度不断变化,但我不希望它们增加(对不起)当您创建
类型INT\u ARGB的缓冲图像
(或者任何类型INT*
,真的),您正在创建一个INT
支持数组来保存像素,这正是宽度*高度
的长度。由于Javaint
是32位或4个字节,因此此数组将使用width*height*4
字节。代码中的DataBuffer
只是这个后备数组的薄薄包装
所以,你看到的增长,完全是预料之中的。根据堆的大小,在尝试创建更大的BufferedImage
s时,会在某个时候耗尽内存
突然出现负值的原因很简单,就是您的表达式:
buff.getSize() * DataBuffer.getDataTypeSize(buff.getDataType()) / 8
当buff.getSize()
变得足够大时,将导致一个错误
作为Java语言中的*
和/
运算符,表达式将从左到右求值,乘法将溢出,即使最终结果(除以8后)应为有效的int
。您可能可以通过添加括号来解决此问题,强制先进行除法:
buff.getSize() * (DataBuffer.getDataTypeSize(buff.getDataType()) / 8)
或者简单地使用long
s:
(long) buff.getSize() * (long) DataBuffer.getDataTypeSize(buff.getDataType()) / 8L
请发一封电子邮件。您的代码片段不够,如果缺少,至少会循环一次,但可能会更多。我想OP想知道,尽管对象创建参数是恒定的(宽度、高度,TYPE\u INT\u ARGB
),为什么计算的大小会发生变化(增加)所以理论上,输出应该总是相同的值。我认为2个负数的意思是,它们是整数,并且超过了整数的大小。。也许可以确定这就是产生不断增加的输出的代码?如果我尝试此循环,输出将保持不变。您的结果与不断增加的宽度
和高度
值一致(使用平方根,我计算的值为43、57、76、101、134、177…等等)。因此,您没有显示实际运行的代码。使用您发布的代码,我可以确认@P.J.Meisch的发现,输出是恒定的。