【发布时间】:2022-01-23 23:27:30
【问题描述】:
我正在尝试编写一个 REST api 以允许用户在 Spring 启动时下载大文件(即 > 2GB)。我遇到了“Java Heap outOfMemoryException”。我试图对问题进行分类,我看到 HttpServetResponse 对象的类型是:ContentCachingResponseWrapper。 此类缓存写入输出流的所有内容,当缓存的数据大小变为 258MB 左右时,我得到 OutOfMemoryException。为什么是 248 MB,因为 JVM 有 256 MB 的堆内存。
ContentCachingResponseWrapper 中的默认 flushBuffer() 方法为空。如果我尝试调用用于将数据从缓存复制到流的 copyBodyToResponse(),它可以正常工作,但它也会关闭流。这导致只向客户端发送第一块数据。
有什么建议吗?
public void myDownloader(HttpServletRequest request, HttpServletResponse response) {
//response.getClass() is: ContentCachingResponseWrapper
byte[] buffer = new byte[1048576]; // 1 MB Chunks
FileInputStream inputStream = new FileInputStream(PATH_TO_SOME_VALID_FILE);
int bytesRead= 0;
ServletOutputStream outputStream = response.getOutputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
outputStream.flush();
response.flushBuffer();
}
}
我收到以下错误:
Caused by: java.lang.OutOfMemoryError: Java heap space
at org.springframework.util.FastByteArrayOutputStream.addBuffer(FastByteArrayOutputStream.java:303) ~[spring-core-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.util.FastByteArrayOutputStream.write(FastByteArrayOutputStream.java:118) ~[spring-core-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
at org.springframework.web.util.ContentCachingResponseWrapper$ResponseServletOutputStream.write(ContentCachingResponseWrapper.java:239) ~[spring-web-5.2.8.RELEASE.jar!/:5.2.8.RELEASE]
【问题讨论】:
-
现在是 Spring - 返回一个
Resource并让 Spring 处理它。你为什么要自己处理这个? -
@borisTheSpider 谢谢。您的意思是 ResponseEntity
,Spring 会将资源分块并发送给客户端吗?
标签: java spring-boot