Невозможно записать в DataOutputStream сверх определенного размера - OutOfMemoryError
У меня есть следующий код, который создает исключение 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
Исключение возникает, когда я пытаюсь записать в dataOS за 342814942.
Может ли кто-нибудь помочь мне справиться с этим?
Спасибо!
2 ответа
Он не имеет ничего общего с DataOutputStream (который не поддерживает никаких данных) и со всем, что связано с вашим основным потоком conn.getOutputStream()
, сейчас вы не указали соответствующий код, но я собираюсь предположить, что "conn" является экземпляром HttpURLConnection. Я полагаю, что outputtream для HttpURLConnection буферизует вывод, чтобы он мог определить длину вывода (если вы не установили это явно). если вы знаете длину вывода, вы можете установить это непосредственно с помощью HttpURLConnection.setFixedLengthStreamingMode
или вы можете позвонить HttpURLConnection.setChunkedStreamMode
разрешить отправку данных в виде фрагментов, а не буферизовать их целиком в памяти.
в будущем, когда вы столкнетесь с OOME, вы всегда должны генерировать дамп кучи и открывать его в профилировщике памяти. это почти всегда сразу покажет вам, где проблема (например, в основном потоке, а не в DataOutputStream).
В зависимости от реализации OutputStream запись может буферизовать содержимое в памяти, а не отправлять его. Если вы буферизуете достаточно содержимого, вам, конечно, не хватит памяти.
Через определенный промежуток времени, возможно, каждый раз, когда вы проходите цикл OutputStream.flush()
, Если используется буфер, это очистит его.