質問: new BufferedOutputStream(response.getOutputStream()); wb.write(out); } catch (IOException e) { e.printstactrace(); } finally { try { wb.close(); } catch (IOException e) { e.printstactrace(); } } } ``` 追記 (1)ボトルネック部分ですが、上記コードのwb.write(out)の部分となります。それ以外は、時間はかかっていない状況となります。 なお、wb.write(out)はローカルにあるファイルをローカルにダイアログでダウンロードで返しています。 (2)ローカルでホストはMacゲストがWin7の64bit メモリ8Gで動作させていてます。 (3)jvmのヒープヒープサイズは以下に設定しております。 -Xmx2g -Xms2048m -Xmx4098m (4)該当のエクセルファイルは3M程度のエクセルを読み込みこむ形となります。 そのファイルに対して、データを横10列のものもあれば、150列のものもあり、行数は、数千行~数万行を、書き込む形となります。 当該重いのは、行数は、数千行ですが、横が150列程度あります。 数式が多く設定されていまして、また細部にこだわる仕様のため、書式も多く設定されております。 追記2 CPU/memory監視状況を添付します。 メモリなど多めに割り当てているため、 マシンに負荷はかかっていないですが、 エクセルへの書き込みとそのダウンロードが非常に重い状況です。 ![CPU/memory監視状況](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/a6752b298360ecb5b346b89cd74aa066.png)
回答: ダメ元ですが、 アプリサーバーのJVMのメモリーに余裕があるなら、 `BufferedOutputStream`のバッファーサイズを増やしてみるとか。 おそらくExcelの書き出し側で遅いので改善は見込めないと思いますが。 ``` OutputStream out = new BufferedOutputStream(response.getOutputStream(), 65536); // デフォルトは8192 ``` ... 本格的に調査するなら、プロファイリングを行って、 特に遅い箇所(ボトルネック)を突き止める必要があります。 JDKに **Java VisualVM** (`jvisualvm`)というプロファイラーが標準搭載されていますので、 それを使ってみるのも手です。 ただプロファイリングは難易度が高いですし、時間もかかります。 ... あとは代替策を取るという手もあります。 Excelを作るのとダウンロードを分けるとか。 これはこれで仕組みを作るのはちょっと手間ですけどね。