我有一个在 Tomcat 7 上运行的 Servlet 应用程序。我在 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 参数才能防止出现此问题。但说真的,我的情况出了什么问题?
是否有最佳实践来处理像我的情况这样的文件上传?
我能以某种方式避免这个问题吗?我的意思是,当 5GB 不足以进行 3-5 次并行上传时,我需要多少资源来进行数百次并行上传?
是我的应用程序太糟糕了还是文件上传占用这么多资源是正常的?
以下是在 Grails Controller 中处理上传的代码:
CommonsMultipartFile file = (CommonsMultipartFile) request.getFile('image')
file.transferTo(new File("${storagePath}${fullFileName}"))
上传后,我进行了大量图像处理。有没有办法对进程进行排队?
答案1
老实说,5G 的堆已经很多了。请向我们展示处理上传的代码路径,并提供一些有关用户通常上传的文件大小和数量的信息。
这也可能对您有所帮助(如果您将 commons fileupload 与 Spring 的 MultipartFile 一起使用):https://stackoverflow.com/questions/1693810/how-can-i-avoid-outofmemoryerrors-when-using-commons-fileuploads-diskfileitem-t
答案2
内存使用取决于应用程序的设计用途以及所有用户正在做什么。因此,实际上没有人可以评论此应用程序是否需要指定数量的内存。正如您所说,您的解决方案是按照错误消息所示操作并增加 Java 堆空间量。