私はHttpURLConnection
サーバーにファイルを書き込むために使用していますが、その一部は非常に大きいものです。
final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
しばらく前に、1GB以上のオブジェクトの書き込みで問題が発生しました。より管理しやすいチャンクサイズをストリーミングするように設定することで、これを修正しました。
final int bufferSize = 1024 * 1024;
[...]
conn.setChunkedStreamingMode(bufferSize);
その後、私のラップトップでは正常に動作していましたが、他のマシンではクラッシュしていました。調査の結果、出力ストリームへの書き込み時に発生したメモリ不足エラーが原因であることがわかりました。
final OutputStream out = conn.getOutputStream();
final long bytesWritten = IOUtils.copyLarge(in, out);
copyLargeルーチン内で、4096バイトの262145回の反復を実行でき、1GBのラインを超えようとすると失敗することがわかりました。より多くのメモリをJavaアプリケーションに割り当てることで、これらのクラッシュを防ぐことができたようですが、それは不要なはずだと思いました。1 MBのチャンクを書き込んでいる場合は、はるかに少ない反復で失敗するか、問題なく1MBを繰り返し書き込む必要があります。
更新:ChunkedStreamingModeが実際に一部のマシンで呼び出されていなかったという行設定が判明しました。固定/チャンクストリーミングモードを設定しない場合、HttpURLConnectionはすべてをPosterOutputStream/ByteArrayOutputStreamに送信するだけです。