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

Java 无法写入超过特定大小的DataOutputStream-OutOfMemoryError,java,out-of-memory,dataoutputstream,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(

我有以下生成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的数据操作系统时,会发生异常

有人能帮我处理一下吗


谢谢

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


每隔一段时间,也许每次通过循环时,您都应该调用。如果有一个缓冲区正在使用,这将清除它。

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


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

正如sharakan所说,您应该定期刷新缓冲区,但如果确实不想刷新,请增加JVM的内存分配(-Xmx参数启动Java时)。几乎每个缓冲数据的流实现都会在内部缓冲区满时自动刷新数据。@jtahlborn这不会让我感到惊讶,但据我所知,这不是合同的一部分。也许你可以举个例子?java中的每个流实现,除了http输出流试图确定输出长度时的情况。jtahlborn:非常感谢。问题确实与conn.getOutputStream()有关。是的,它是一个httpurl连接。抱歉没有具体说明。我尝试将setFixedLengthStreamingMode设置为文件长度,它似乎超出了以前的大小。非常感谢。我正在使用dataOS将数据上传到服务器。因此,当我使用setChunkedStreamMode时,我是否必须以不同的方式处理上载?现在我调用conn.getResponseCode()进行上传。请建议。@Ram-首先,您不需要DataOutputStream(直接使用conn输出流)。如果你使用分块流,你不需要做任何不同的事情。另一端的服务器需要支持分块编码(但大多数都支持)。非常感谢。我会试试看。