Я использую HttpURLConnection
для записи файлов, некоторые из которых довольно большие, на сервер.
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
В то время как у меня были проблемы с записью объектов 1 ГБ или более. Я исправил это, установив для потока более управляемый размер блока.
final int bufferSize = 1024 * 1024;
[...]
conn.setChunkedStreamingMode(bufferSize);
Тогда он работал отлично на моем ноутбуке, но на других машинах он рушился. В ходе расследования я обнаружил, что причиной была ошибка из памяти, возникающая при записи в выходной поток.
final OutputStream out = conn.getOutputStream();
final long bytesWritten = IOUtils.copyLarge(in, out);
Внутри процедуры copyLarge я обнаружил, что он смог выполнить 262145 итераций 4096 байт, если не попытался пересечь линию 1 ГБ. Выделение большего объема памяти для приложения java, казалось, предотвращало эти сбои, но я думал, что это должно быть ненужным. Если он записывает куски размером 1 МБ, то либо он должен терпеть неудачу с гораздо меньшим количеством итераций, либо повторно писать 1 МБ без проблем.
UPDATE: Выключает настройку строки, на которой ChunkedStreamingMode фактически не вызывается на некоторых машинах. Если вы не установили режим фиксированной/помеченной потоковой передачи, HttpURLConnection просто отправит все в PosterOutputStream/ByteArrayOutputStream.