【问题标题】:Unable to write into DataOutputStream beyond a specific size - OutOfMemoryError无法写入超过特定大小的 DataOutputStream - OutOfMemoryError
【发布时间】:2012-04-24 01:20:05
【问题描述】:

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

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

谢谢!

【问题讨论】:

  • 就像 sharakan 所说,您应该定期刷新缓冲区,但如果您真的不想刷新,请增加 JVM 的内存分配(启动 Java 时的 -Xmx 参数)。

标签: java out-of-memory dataoutputstream


【解决方案1】:

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

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

【讨论】:

  • jtahlborn:非常感谢。问题确实与 conn.getOutputStream() 有关。是的,它是一个 HttpURLConnection。抱歉没有具体说明。我尝试将 setFixedLengthStreamingMode 设置为文件长度,它似乎超出了以前的大小。谢谢你。我正在使用 dataOS 将数据上传到服务器。因此,当我使用 setChunkedStreamMode 时,我是否必须以不同的方式处理上传?现在我调用 conn.getResponseCode() 来上传。请提出建议。
  • @Ram - 一方面,您不需要 DataOutputStream(只需直接使用 conn 输出流)。如果您使用分块流式传输, 不需要做任何不同的事情。另一端的服务器需要支持分块编码(但大多数都支持)。
  • 非常感谢。我会试试看。
【解决方案2】:

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

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

【讨论】:

  • 几乎所有缓冲数据的流实现都会在内部缓冲区已满时自动刷新数据。
  • @jtahlborn 这不会让我感到惊讶,但据我所知,这不是合同的一部分。或许你可以举个例子?
  • java 中的每个流实现,除了尝试确定输出长度时的 http 输出流。
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多