5

我有以下代码会产生 OutOfMemory 异常:

byte[] buf = new byte[10240];
int len = 0;
DataOutputStream dataOS = new DataOutputStream(conn.getOutputStream());
while ((len = _inputStream.read(buf)) > 0) {
    System.out.println("len : " + len);
    System.out.println("Going to write buf into dataOS : " + buf.length);
    dataOS.write(buf, 0, len);
    System.out.println("dataOS.size() : " + dataOS.size());
}
_inputStream.close();

以下是调试输出的最后几行:

len : 10240
Going to write buf into dataOS : 10240
dataOS.size() : 342804702
len : 10240
Going to write buf into dataOS : 10240
dataOS.size() : 342814942
len : 10240
Going to write buf into dataOS : 10240

当我尝试写入超过 342814942 的 dataOS 时发生异常。

有人可以帮我处理这个吗?

谢谢!

4

2 回答 2

14

它与 DataOutputStream (不维护任何数据)无关,与您的底层流无关conn.getOutputStream()。现在,您还没有在那里显示相关代码,但我猜“conn”是 HttpURLConnection 的一个实例。我相信 HttpURLConnection 的输出流缓冲输出,以便它可以确定输出长度(除非您明确设置它)。如果您知道输出长度,您可以直接使用设置HttpURLConnection.setFixedLengthStreamingMode,或者您可以调用HttpURLConnection.setChunkedStreamMode以允许数据以块的形式发送,而不是完全缓冲在内存中。

将来,当您遇到 OOME 时,您应该始终生成堆转储并在内存分析器中打开它。这几乎总是会立即向您显示问题出在哪里(例如在底层流中,而不是在 DataOutputStream 中)。

于 2012-04-24T01:32:50.240 回答
1

根据 OutputStream 的实现,写入可能会在内存中缓冲内容,而不是实际发送。如果你缓冲足够的内容,你当然会耗尽内存。

在某个时间间隔,也许每次通过你的循环,你应该调用OutputStream.flush(). 如果有缓冲区正在使用,那将清除它。

于 2012-04-24T01:30:25.330 回答