ServletOutputStream
IBM Websphere Application Server v6 と Java 1.4 を使用しており、ユーザーがダウンロードできるように大きな CSV ファイルを に書き込もうとしています。現在、ファイルのサイズは 50 ~ 750 MB です。
小さいファイルはそれほど大きな問題を引き起こしていませんが、大きいファイルではヒープに書き込まれているように見え、それが OutOfMemory エラーを引き起こし、サーバー全体をダウンさせています。
これらのファイルは、HTTPS 経由で認証されたユーザーにのみ提供できます。そのため、Apache に貼り付けるのではなく、サーブレットを介して提供しています。
私が使用しているコードは次のとおりです(これに関するいくつかの綿毛が削除されました):
resp.setHeader("Content-length", "" + fileLength);
resp.setContentType("application/vnd.ms-excel");
resp.setHeader("Content-Disposition","attachment; filename=\"export.csv\"");
FileInputStream inputStream = null;
try
{
inputStream = new FileInputStream(path);
byte[] buffer = new byte[1024];
int bytesRead = 0;
do
{
bytesRead = inputStream.read(buffer, offset, buffer.length);
resp.getOutputStream().write(buffer, 0, bytesRead);
}
while (bytesRead == buffer.length);
resp.getOutputStream().flush();
}
finally
{
if(inputStream != null)
inputStream.close();
}
別のFileInputStream
ファイルに書き込むか、書き込みを完全に削除するかのように問題を引き起こしているようには見えませんが、メモリ使用量は問題ではないようです。
私が考えているのresp.getOutputStream().write
は、データがクライアントに送信されるまでメモリに保存されているということです。そのため、ファイル全体が読み取られて保存されresp.getOutputStream()
、メモリの問題やクラッシュが発生する可能性があります。
私はこれらのストリームをバッファリングしようとしましたが、 からjava.nio
のチャネルを使用しようとしましたが、メモリの問題に少しの違いもないようです。OutputStream
また、ループの反復ごとに 1 回とループの後にフラッシュしましたが、これは役に立ちませんでした。