0

I'm getting an OutOfMemoryException while trying to download several files. All of them are being downloading simultaneously and their size is over 200MB more or less. I'm using Spring 3.2.3 and java 7. This is a call from a REST request. This is the code:

@RequestMapping(value = "/app/download", method = RequestMethod.GET, produces = MediaType.MULTIPART_FORM_DATA_VALUE)
public void getFile(@PathVariable String param, HttpServletResponse response) {
    byte[] fileBytes = null;
    String fileLength = null;
    try {
        // Firstly looking for the file from disk
        Path fileFromDisk = getFileFromDisk(param);
        InputStream is = null;

        long fileLengthL = Files.size(fileFromDisk);
        fileLength = String.valueOf(fileLengthL);

        // Preparing data for response
        String fileName = "Some file name.zip";
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        response.setHeader("Content-Length", fileLength);

        is = Files.newInputStream(fileFromDisk);

        IOUtils.copy(is, response.getOutputStream());
        response.flushBuffer();
    } catch (Exception e) {
        // Exception treatment
    }
}

IOUtils is the library from Apache to work with files. The code works perfectly until we have several requests at a time. I think the problem is the response is filled with all the data from the file and it is not freed from the JVM until the download is completed. I would like to know if there is a way to chunk the response or similar to avoid filling the heap space with all the data at a time.

¿Any ideas?

Thank you very much in advance.

Wallzs
  • 1
  • 2

3 Answers3

0

Have you given your dev environment enough memory?

I use Eclipse and its default memory allocation is 512m which has caused me issues when using Spring.

  1. If you are using eclipse go into eclipses main folder and open a file called eclipse.ini.

  2. There will be a line in there that says -Xmx512m.

  3. Change that to what ever memory you would like to allocate to your Dev enviroment I would normally go at least -Xmx1024m at least.

I hope this helps.

Gambit
  • 21
  • 3
  • Yep, I've tried. Sorry, I didn't mention it: I have configured 1024MB and it is not enough because of the size of the files that are being downloaded simultaneously. I'm thinking about putting more memory, but I'm afraid it is only a temporary solution because in the future I'll probably have several downloads at a time with big files. Anyway, thank you very much for your response. – Wallzs Feb 14 '14 at 13:28
  • Hmmm yeah I'm not sure then tbh. And definitely agree if you start going above 1024MB you probably have an underlying issue that needs addressing. Sorry I couldn't help, I'm sure someone smarter then me will have a good response :p Good luck. – Gambit Feb 14 '14 at 13:59
0

The content type set with the 'produces' attribute looks to be incorrect. Set the proper content type directly on the response object with the setContentType method. Also try using the setContentLength method to set the content length.

Jukka
  • 4,583
  • 18
  • 14
0

After reading and reading I've reached this conclusion: The output stream of the response object has to be completely filled, it can't be returned as little blocks of data to the browser or client. So the file size is loaded whatever it will be.

My personal solution is let doing the hard work a third party. My requirements need to have multiple downloads of big files at the same time: as my memory is not enough I'm using an external entity that provides me those files as a temporary URL.

I don't know if it is the best way, but is working for me.

Thank you anyway for your responses.

Wallzs
  • 1
  • 2