5

使用 Commons FileUpload 1.2.1 将大型 (>300MB) 文件上传到 servlet 时,出现 OutOfMemoryErrors。这似乎很奇怪,因为使用 DiskFileItem 的全部目的是防止(可能很大)文件驻留在内存中。我使用的是 10KB 的默认大小阈值,所以这就是应该加载到堆中的所有内容,对吧?这是部分堆栈跟踪:

java.lang.OutOfMemoryError
       at java.io.FileInputStream.readBytes(Native Method)
       at java.io.FileInputStream.read(FileInputStream.java:177)
       at org.apache.commons.fileupload.disk.DiskFileItem.get(DiskFileItem.java:334)
       at org.springframework.web.multipart.commons.CommonsMultipartFile.getBytes(CommonsMultipartFile.java:114)

为什么会这样?我缺少一些配置吗?除了增加我的堆大小之外,还有什么提示/技巧可以避免这种情况?

我真的不应该增加我的堆,因为理论上应该从这个操作加载到内存中的最多是 10KB 多一点。另外,我的堆最大值(-Xmx)已经设置为 1GB,应该足够了。

4

2 回答 2

10

在处理文件上传时,尤其是大文件,您应该将这些文件作为流处理,然后将其放入中等大小的内存缓冲区中,然后直接复制到输出文件中。错误的做法是在写出之前将整个内容吸入内存。

commons-upload 上的文档在中间下方提到了如何“处理文件上传”。如果您记得以合理大小的块(例如,1 MB)从输入流复制到输出流,那么您应该没有问题。

于 2009-11-07T17:47:27.320 回答
1

虽然 Carl Smotricz 的答案在一般情况下可能更好,但您得到的例外是此处报告的 JVM 错误:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6478546

于 2012-04-18T16:18:01.173 回答