0

Tomcat 7 で実行されているサーブレット アプリケーションがあります。setenv.sh で次のように設定します。

CATALINA_OPTS="
-server 
-Xms1G 
-Xmx5G
-XX:MaxPermSize=512m
-Dfile.encoding=UTF-8";

サーバーは Ubuntu 12.04LTS で実行され、6 コアと 8GB の RAM を備えています。私のアプリケーションは、ユーザーが画像をアップロードできる Grails/Spring/Java アプリです。3 ~ 5 人のユーザーが同時に画像のアップロードを開始する場合があります。これらの状況では、次のエラーが原因で Tomcat がクラッシュします。

java.lang.OutOfMemoryError: Java heap space

この問題を防ぐには、Tomcat の Xmx パラメータを増やす必要があることを知っています。しかし、真剣に私の場合は何が悪いのでしょうか?

  1. 私のシナリオのようにファイルのアップロードを処理するためのベスト プラクティスはありますか?

  2. どうすればこの問題を防ぐことができますか? つまり、3 ~ 5 個の並列アップロードに 5GB では不十分な場合、何百もの並列アップロードに必要なリソースはどれくらいですか?

  3. 私のアプリはとても悪いのでしょうか、それともファイルのアップロードに多くのリソースを消費するのは普通のことですか?

注: ユーザーがアップロードするファイルは 2 ~ 8 MB です。

これは、私のビューでアップロードを行う方法です。

   <g:form method="post" action="save" enctype="multipart/form-data">
    <input type="file" name="file"/>
    <input type="submit"/>
   </g:form>

そして私のコントローラーで:

def file = request.getFile('image')
byte [] byteFile = file.getBytes()

config/spring/resource.groovy では、次のことを行いました。

beans = { 
  multipartResolver(org.springframework.web.multipart.commons.CommonsMultipartResolver){

        // Max in memory 100kbytes
        maxInMemorySize=102400

    }

} 

アップロードしたファイルは画像です。それらはスケーリングされ、ディスクに保存されます。

画像は次のように保存されます。

bytes [] currentImage = // some image in bytes ...
def newFile = new FileOutputStream(fullPath)
newFile.write(currentImage)
newFile.close()
4

1 に答える 1

1

ファイルの内容全体をメモリに読み込まないようにするにMultipartFile.getBytes()は、 を使用しないでください。MultipartFile.getInputStream()

コードを次のように変更します。

def file = request.getFile('image')
InputStream inputStream = file.inputStream

アップロードされたファイルで何をするかについては言及していませんが、ヒープの使用を最小限に抑えたい場合は、アプリケーションのレイヤー全体で渡しInputStream、に変換しないようにしてください。byte[]

于 2013-08-26T13:00:48.780 に答える