我在尝试下载多个文件时遇到内存不足异常。所有这些都是同时下载的,它们的大小或多或少超过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,这导致了我在使用弹簧时出现问题。
-
如果您使用的是 eclipse,请进入 eclipses 主文件夹并打开一个名为 Eclipse.ini 的文件。
-
那里会有一行说-Xmx512m。
-
将其更改为要分配给开发环境的内存我通常至少会去 -Xmx1024m。
我希望这有所帮助。
使用"produces"属性设置的内容类型看起来不正确。使用 setContentType 方法直接在响应对象上设置正确的内容类型。还可以尝试使用 setContentLength 方法来设置内容长度。
经过阅读和阅读,我得出了这个结论:响应对象的输出流必须完全填充,它不能作为小数据块返回给浏览器或客户端。因此,无论文件大小如何,都会加载文件大小。
我个人的解决方案是让第三方做艰苦的工作。我的要求需要同时多次下载大文件:由于我的内存不足,我正在使用一个外部实体,该实体为我提供这些文件作为临时 URL。
我不知道这是否是最好的方法,但对我有用。
无论如何,感谢您的回复。