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

我有以下代码生成OutOfMemoryexception:

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时发生exception。

有人可以帮我处理这件事吗?

谢谢!

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

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

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

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