无法写入超出特定大小的DataOutputStream - OutOfMemoryError

时间:2012-04-24 01:20:05

标签: java out-of-memory dataoutputstream

我有以下代码产生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时会发生异常。

有人可以帮我解决这个问题吗?

谢谢!

2 个答案:

答案 0 :(得分:14)

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

将来,当遇到OOME时,您应该始终生成堆转储并在内存分析器中打开它。几乎总会立即向您显示问题所在(例如在基础流中, DataOutputStream)。

答案 1 :(得分:1)

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

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