ユーザーがリンクをクリックしてデータのリストをダウンロードできる Web アプリケーションがあります。それが行うことは、MS sql サーバー データベースでストアド プロシージャを起動することです。つまり、14 列とすべての文字列で行をフェッチします。それを取得して結果セットから抽出したら、それをクライアントのマシン上の csv ファイルに直接ストリーミングします。そうすれば、ストリーミング操作を開始する前に、メモリ内に中間ドメイン オブジェクト (返される行数に等しい) を作成して節約できます。また、結果セット全体がメモリにロードされるまで待機しません。ただし、たとえば、そのようなデータのインスタンスが 80000 あるクライアントの場合、メモリはまだ 50 mb 急増しています。その後、約 20 mb の減少があり、しばらくの間そのレベルにとどまります。jconsole で Perform GC を実行すると、残りの 30 MB も解放されます。何が原因でそれがしばらく続くのかわかりません。また、50 mb のスパイクは、1.2 ギガのメモリで実行されているアプリケーションでは受け入れられません。より大きなクライアントの場合、400 mb まで跳ね上がり、アプリケーションがフリーズするか、OOM が発生します。これを達成する方法について何か提案はありますか? 注意してください - 私は同じことを別の場所に実装しました.5秒で同じサイズで異なるデータ(6列)のファイルがダウンロードされ、メモリスパイクはわずか5 MBです。この場合、Sql Mnagament スタジオで実行した場合でも、ストアド プロシージャを実行するのにわずか 4 秒しかかかりませんでした。しかし、私が大きなスパイクを得ているものは、クエリ自体の実行に45秒かかり、多くの検証を通過するデータに基づいています. それは悪影響を及ぼしますか?プリペアドストメントの setFetchSize() で 1000 のチャンクをフェッチしているので、そうならないことを望んでいました より大きなクライアントの場合、400 mb まで跳ね上がり、アプリケーションがフリーズするか、OOM が発生します。これを達成する方法について何か提案はありますか? 注意してください - 私は同じことを別の場所に実装しました.5秒で同じサイズで異なるデータ(6列)のファイルがダウンロードされ、メモリスパイクはわずか5 MBです。この場合、Sql Mnagament スタジオで実行した場合でも、ストアド プロシージャを実行するのにわずか 4 秒しかかかりませんでした。しかし、私が大きなスパイクを得ているものは、クエリ自体の実行に45秒かかり、多くの検証を通過するデータに基づいています. それは悪影響を及ぼしますか?プリペアドストメントの setFetchSize() で 1000 のチャンクをフェッチしているので、そうならないことを望んでいました より大きなクライアントの場合、400 mb まで跳ね上がり、アプリケーションがフリーズするか、OOM が発生します。これを達成する方法について何か提案はありますか? 注意してください - 私は同じことを別の場所に実装しました.5秒で同じサイズで異なるデータ(6列)のファイルがダウンロードされ、メモリスパイクはわずか5 MBです。この場合、Sql Mnagament スタジオで実行した場合でも、ストアド プロシージャを実行するのにわずか 4 秒しかかかりませんでした。しかし、私が大きなスパイクを得ているものは、クエリ自体の実行に45秒かかり、多くの検証を通過するデータに基づいています。それは悪影響を及ぼしますか?プリペアドストメントの setFetchSize() で 1000 のチャンクをフェッチしているので、そうならないことを望んでいました これを達成する方法について何か提案はありますか? 注意してください - 私は同じことを別の場所に実装しました.5秒で同じサイズで異なるデータ(6列)のファイルがダウンロードされ、メモリスパイクはわずか5 MBです。この場合、Sql Mnagament スタジオで実行した場合でも、ストアド プロシージャを実行するのにわずか 4 秒しかかかりませんでした。しかし、私が大きなスパイクを得ているものは、クエリ自体の実行に45秒かかり、多くの検証を通過するデータに基づいています. それは悪影響を及ぼしますか?プリペアドストメントの setFetchSize() で 1000 のチャンクをフェッチしているので、そうならないことを望んでいました これを達成する方法について何か提案はありますか? 注意してください - 私は同じことを別の場所に実装しました.5秒で同じサイズで異なるデータ(6列)のファイルがダウンロードされ、メモリスパイクはわずか5 MBです。この場合、Sql Mnagament スタジオで実行した場合でも、ストアド プロシージャを実行するのにわずか 4 秒しかかかりませんでした。しかし、私が大きなスパイクを得ているものは、クエリ自体の実行に45秒かかり、多くの検証を通過するデータに基づいています. それは悪影響を及ぼしますか?プリペアドストメントの setFetchSize() で 1000 のチャンクをフェッチしているので、そうならないことを望んでいました しかし、私が大きなスパイクを得ているものは、クエリ自体の実行に45秒かかり、多くの検証を通過するデータに基づいています. それは悪影響を及ぼしますか?プリペアドストメントの setFetchSize() で 1000 のチャンクをフェッチしているので、そうならないことを望んでいました しかし、私が大きなスパイクを得ているものは、クエリ自体の実行に45秒かかり、多くの検証を通過するデータに基づいています. それは悪影響を及ぼしますか?プリペアドストメントの setFetchSize() で 1000 のチャンクをフェッチしているので、そうならないことを望んでいました
ここにコードのスニペットがあります
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
OutputStream outputStream = null;
BufferedWriter bufferedWriter = null;
try
{
response.setContentType("application/save");
response.setHeader("Content-Disposition", "attachment; filename="
+ link.getFileName());
outputStream = response.getOutputStream();
bufferedWriter = new BufferedWriter(new OutputStreamWriter(
outputStream));
connection = dataSource.getConnection();
statement = connection.prepareStatement(link.getQuery());
statement.setFetchSize(1000);
statement.setInt(1, form.getSelectedClientId());
rs = statement.executeQuery();
while (rs.next())
{
bufferedWriter
.write(getCsvRowString(new String[]
{ rs.getString(1), rs.getString(2), rs.getString(3),
rs.getString(4), rs.getString(5),
rs.getString(6), rs.getString(7),
rs.getString(8), rs.getString(9),
rs.getString(10), rs.getString(11),
rs.getString(12), rs.getString(13),
rs.getString(14), rs.getString(15),
rs.getString(16), rs.getString(17),
rs.getString(18) }));
}
} catch (final Exception e)
{
log.error("Error in downloading extracts " + e.getMessage());
throw e;
} finally
{
if (bufferedWriter != null)
{
bufferedWriter.flush();
bufferedWriter.close();
}
if (outputStream != null)
{
outputStream.close();
}
rs.close();
statement.close();
connection.close();
}