Reputation: 1376
I am attempting to download over 100mb video mp4 file by using below code. But i am getting "java.lang.OutOfMemoryError: Java heap space" while downloading.
Using jdk1.7 & Spring MVC.
I have refered below SO links but none works for me.
how to download large files without memory issues in java
java.lang.OutOfMemoryError: Java heap space while downloading a large file from an URL
Please help me to resolve this.
OutputStream outStream = null;
FileInputStream inputStream = null;
try {
ServletContext context = request.getSession().getServletContext();
String fileName = Integer.toString(fileId);
filePath = fileName+".mp4";
File downloadFile = new File(filePath);
inputStream = new FileInputStream(new File(filePath));
// get MIME type of the file
String mimeType = context.getMimeType(filePath);
if (mimeType == null) {
mimeType = "application/octet-stream";
}
response.setContentType(mimeType);
response.setContentLength((int) downloadFile.length());
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",downloadFile.getName());
response.setHeader(headerKey, headerValue);
outStream = response.getOutputStream();
byte[] buffer = new byte[1024];
int bytesRead = 0, bytesBuffered = 0;
while((bytesRead = inputStream.read(buffer)) > -1) {
outStream.write(buffer, 0, bytesRead);
bytesBuffered += bytesRead;
if (bytesBuffered > 1024 * 1024) { //flush after 1MB
bytesBuffered = 0;
outStream.flush();
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outStream != null) {
outStream.flush();
outStream.close();
}
}
Upvotes: 1
Views: 3616
Reputation: 6818
I tried below code with 500 MB file and did not receive out of memory error
OutputStream outStream = response.getOutputStream();
String mimeType = "application/zip";
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"",
"abc.zip");
response.setHeader(headerKey, headerValue);
response.setContentType(mimeType);
response.setStatus(HttpServletResponse.SC_OK);
File downloadFile = new File("file path");
InputStream inputStream = new FileInputStream(downloadFile);
int n = 0;
byte[] buf = new byte[1024];
while ((n = inputStream.read(buf)) != -1) {
outStream.write(buf, 0, n);
}
inputStream.close();
outStream.flush();
outStream.close();
and JVM settings are:
-XX:PermSize=256m
-XX:MaxPermSize=512m
-Xms1024m
-Xmx2048m
-Dosgi.requiredJavaVersion=1.8
-XX:+UseG1GC
-XX:+UseStringDeduplication
Upvotes: 2
Reputation: 311054
You need to call HttpServletResponse.flushBuffer()
, not just OutputStream.flush()
, and rather more frequently.
Upvotes: 1