5

Commons FileUpload 1.2.1を使用して大きな(> 300MB)ファイルをサーブレットにアップロードすると、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 に答える