OutOfMemoryError 同时使用 Spring 处理多个下载请求



我在尝试下载多个文件时遇到内存不足异常。所有这些都是同时下载的,它们的大小或多或少超过200MB。我正在使用Spring 3.2.3和Java 7。这是来自 REST 请求的调用。这是代码:

@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是Apache的用于处理文件的库。代码完美运行,直到我们一次有多个请求。我认为问题是响应充满了文件中的所有数据,并且在下载完成之前不会从 JVM 中释放它。我想知道是否有办法对响应进行分块或类似方法,以避免一次用所有数据填充堆空间。

¿有什么想法吗?

提前非常感谢你。

您是否为开发环境提供了足够的内存?

我使用 Eclipse,它的默认内存分配是 512m,这导致了我在使用弹簧时出现问题。

  1. 如果您使用的是 eclipse,请进入 eclipses 主文件夹并打开一个名为 Eclipse.ini 的文件。

  2. 那里会有一行说-Xmx512m。

  3. 将其更改为要分配给开发环境的内存我通常至少会去 -Xmx1024m。

我希望这有所帮助。

使用"produces"属性设置的内容类型看起来不正确。使用 setContentType 方法直接在响应对象上设置正确的内容类型。还可以尝试使用 setContentLength 方法来设置内容长度。

经过阅读和阅读,我得出了这个结论:响应对象的输出流必须完全填充,它不能作为小数据块返回给浏览器或客户端。因此,无论文件大小如何,都会加载文件大小。

我个人的解决方案是让第三方做艰苦的工作。我的要求需要同时多次下载大文件:由于我的内存不足,我正在使用一个外部实体,该实体为我提供这些文件作为临时 URL。

我不知道这是否是最好的方法,但对我有用。

无论如何,感谢您的回复。

最新更新