5

大きい(> 300MB)ファイルをCommons FileUpload 1.2.1を使用しているサーブレット にアップロードするときに、OutOfMemoryErrorsを取得しています。 DiskFileItemを使用する全体のポイントは、おそらく 大きなファイルがメモリに存在しないようにするためです。私はデフォルトサイズの スレッショルドを使用していますので、それはすべて ヒープにロードする必要がありますか?部分スタックトレースは次のとおりです。大きなファイルをアップロードするために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

関連する問題