简体   繁体   English

Spring参加多个下载请求时出现OutOfMemoryError

[英]OutOfMemoryError while attending multiple download requests with Spring

I'm getting an OutOfMemoryException while trying to download several files. 尝试下载多个文件时出现OutOfMemoryException。 All of them are being downloading simultaneously and their size is over 200MB more or less. 它们全部正在同时下载,其大小或多或少超过200MB。 I'm using Spring 3.2.3 and java 7. This is a call from a REST request. 我正在使用Spring 3.2.3和Java7。这是来自REST请求的调用。 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. IOUtils是Apache的库,用于处理文件。 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. 我认为问题在于响应中充满了文件中的所有数据,并且直到下载完成才从JVM中释放出来。 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. 提前非常感谢您。

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. 我使用Eclipse,其默认内存分配为512m,这在使用Spring时导致了我的问题。

  1. If you are using eclipse go into eclipses main folder and open a file called eclipse.ini. 如果您使用的是eclipse,请进入eclipses主文件夹并打开一个名为eclipse.ini的文件。

  2. There will be a line in there that says -Xmx512m. 那里会有一行显示-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. 将其更改为您想要分配给开发环境的内存,通常我至少会至少达到-Xmx1024m。

I hope this helps. 我希望这有帮助。

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. 使用setContentType方法直接在响应对象上设置适当的内容类型。 Also try using the setContentLength method to set the content length. 也可以尝试使用setContentLength方法设置内容长度。

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. 我的要求需要同时下载多个大文件:由于内存不足,我正在使用一个外部实体,该实体向我提供这些文件作为临时URL。

I don't know if it is the best way, but is working for me. 我不知道这是否是最好的方法,但正在为我工​​作。

Thank you anyway for your responses. 无论如何,谢谢您的答复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM