我们有一个 java 计划任务来在 java 程序中运行查询并将结果发送到基于 Jersey 的 restful web 服务。虽然这在某些情况下似乎可以正常工作,但在一种情况下它不起作用并最终出现Java.lang.OutOfMemoryError: Java heap space
在以下程序中,数据以块的形式流式传输,但对于其中一个查询,数据不会被刷新一次以上。因此,所有块都在内存中累积,导致内存不足异常。
我们已经看到Java - Upload OutputStream as HTTP File Upload HttpURLConnection 超时问题 和 在 Java EE 应用程序中处理大型记录
他们中的许多人建议使用 HTTPClient,但我们希望尽可能避免使用它。
for (int i = 0; i < arr.length(); i++) {
try {
JSONObject obj = arr.getJSONObject(i);
StringBuffer query = new StringBuffer((String) obj.get("query")); // Getting one query from list of queries
int size =500;
int count = 0;
URL url = new URL("http://urltomyserver.com");
java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
httpcon = (HttpURLConnection) url.openConnection();
httpcon.setChunkedStreamingMode(1024 * 1024);
httpcon.setAllowUserInteraction(false);
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
httpcon.setRequestMethod("POST");
OutputStream rawOutStream = httpcon.getOutputStream();
BufferedWriter w = new BufferedWriter(new OutputStreamWriter(rawOutStream));
do {
Query q = new Query(query + " limit " + count + ", " + size);
count += size;
Map[] results = q.runQuery();
JSONArray resultArr = new JSONArray(results);
w.write(resultArr.toString(1));
w.flush();
} while (results != null && results.length > 0);
InputStream inputStream = httpcon.getInputStream();
w.close();
} catch (Exception ex) {
EcwLog.AppendExceptionToLog(ex);
}
}
服务器端接收函数定义如下
public String saveResultsMP(@QueryParam("apuId") final String apuId, @QueryParam("tableName") String tableName, @QueryParam("queryId") String query_id, InputStream uploadedInputStream) {