我遇到了一个我不明白的记忆问题。 我有以下案例
<案例1public byte[] getBytes(InputStream is) throws IOException {
int len;
int size = 1024;
byte[] buf;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
buf = new byte[size];
while ((len = is.read(buf, 0, size)) != -1)
{
bos.write(buf, 0, len);
}
buf = bos.toByteArray();
return buf;
}
Public void dosomething()
{
//instructions
InputStream is = new ByteArrayInputStream(getBytes(bodyPart.getInputStream()));
}
正确无误地工作
但是这个
<案例2Public void dosomething()
{
//instructions
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len;
int size = 1024;
byte[] bufferFichierEntree = new byte[size];
while ((len = bodyPart.getInputStream().read(bufferFichierEntree, 0, size)) != -1)
{
bos.write(bufferFichierEntree, 0, len);
}
InputStream is = new ByteArrayInputStream(bufferFichierEntree);
}
返回一个java.lang.OutOfMemoryError:Java堆空间,不知道为什么? 唯一的区别是,在第一种情况下,我使用的功能与第二种情况不同
答案 0 :(得分:4)
在
while ((len=bodyPart.getInputStream().read(bufferFichierEntree, 0, size)) != -1)
您正在每个循环中创建新的InputStream,因此您只读取每个循环中的第一个字节。
尝试在之前创建输入流,并按照您在第一个示例中的方式使用它。
答案 1 :(得分:1)
原因可能是:
当您使用两种方法时,ByteArrayOutputStream
超出了范围,垃圾收集器(GC)可以清除它。
只使用一种方法,GC无法清除缓冲区,因为它仍然在范围内,除非您使其无效。
当然,另一个原因可能是您每次在循环中创建一个新的InputStream,因为我们不确切知道bodyPart.getInputStream()
的作用。如果是这种情况,请按以下方式解决:
InputStream in = bodyPart.getInputStream();
while ((len = in.read(bufferFichierEntree, 0, size)) != -1)
{
bos.write(bufferFichierEntree, 0, len);
}
答案 2 :(得分:1)
似乎是getInputStream的范围问题,在第一个示例中,您使用的是1个InputStream,在第二个无穷大中,并且每次读取前1000个字节。如果你把它改成喜欢的话;
InputStream is = bodyPart.getInputStream(); while ((len = is.read(bufferFichierEntree, 0, size)) != -1) {
它应该按预期运行。