2009-11-07 44 views
5

文件上傳大(> 300MB)時 利用通用FileUpload 1.2.1一個servlet我收到OutOfMemoryError異常。這似乎很奇怪,因爲 使用DiskFileItem的全部要點是防止(可能 大)文件從駐留在內存中。我使用10KB的缺省大小 門檻,讓這一切都應該永遠被加載到 堆,對不對?以下是部分堆棧跟蹤:如何在使用Commons FileUpload的DiskFileItem上傳大文件時避免OutOfMemoryErrors?

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,這應該是很多。

回答

10

當上傳文件處理,特別是大的,你應該處理這些文件,你啜食入中等大小的內存緩衝區,並直接複製到您的輸出文件流。這樣做的錯誤方法是在寫出來之前將所有東西吸入記憶中。

The doc on commons-upload提到,只是中間的下方,如何「處理文件上傳」。如果你記得以合理大小的塊(比如1 MB)從輸入流複製到輸出流,你應該沒問題。

+1

起初我並不認爲適用於我的情況您的評論,因爲我沒有直接處理文件;我在Spring的MultipartFile類中封裝了FileItem實例。然而,我仔細觀察了代碼,它調用MultipartFile的getBytes(),它返回文件的全部內容。我從MultipartFile中打開我的FileItem,然後按照文檔中的建議處理這些文件。這解決了我的問題。 – rcampbell 2009-11-07 20:32:44

相關問題