我有一个小网站从mysql DB(BLOB字段)获取图片,然后我将它们打印在我的网页上。
对于某些类我读取blob字段,我检查图片尺寸,如果有必要我调整它们,并使用servlet我打印我的页面上的图片。
在每个页面中我都这样做(阅读一些blob字段,检查尺寸,调整大小并打印几张照片)。
保存在DB中的每张照片都不到200 kb。
我用这种方式读取blob字段:
1)InputStream photo = record.getBinaryStream(“blob_field_name”);
2)BufferedImage sourceImage = ImageIO.read(photo);
3)我调整了照片的大小
我经常在tomcat的LOG "Exception in thread "http-bio-12418-exec-26" java.lang.OutOfMemoryError: Java heap space"
我租用的服务器上有自己的虚拟机,我有64 MB的堆空间。
如果我检查堆我有这个结果(对于同一页面有相同的图片):
我怎么知道我的代码是否犯了错误,或者是否是服务器问题?
谢谢
答案 0 :(得分:1)
不要将blob读入内存。整个想法是它们对于正常处理来说太大了。只需读取其输入流并将其写入输出。如果您需要有关blob的额外元数据,请将其存储在另一列中。
答案 1 :(得分:0)
你应该添加这一行:
export MAVEN_OPTS="-Xmx512M -XX:MaxPermSize=512M"
请注意,有些用户报告说双引号存在问题,因此您可能需要使用:
export MAVEN_OPTS=-Xmx512M -XX:MaxPermSize=512M
编辑:
由于您使用的是Tomcat,请使用:
打开tomcat / bin / catalina.sh
add this line to the JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
保存并退出,重启Tomcat
答案 2 :(得分:0)
使用一些内存监控(可以从jVisualVM开始)和自动化测试(Selenium,jMeter)。寻找内存消耗,垃圾收集和内存泄漏。您可以增加堆大小,但如果您遇到一些泄漏,这只能是临时解决方案。
答案 3 :(得分:0)
Java堆大小并不反映“我使用了多少内存”,它反映了“JVM总共要使用多少内存”。
您在提问中提到“每张图片小于200kb”。那是无关紧要的。您正在将其加载到ImageBuffer中,缓冲区并不关心您的压缩JPEG文件是否小于200kb。它至少需要4个字节。图像中的像素。这意味着即使是一个小的80x80 gravatar风格的图像也是25Kb的内存。这适用于您拥有的每张图片。由于您正在重新调整大小,因此需要两倍的时间(一个缓冲区用于源,一个缓冲区用于目标)。由于您正在处理多个请求,因此需要进一步乘以并发请求的数量。
所以你最终不得不使用相当多的资源。我认为更好的设计是预先扩展图像,然后存储两个版本,然后将这两个版本作为流提供(即不要将它们加载到内存中)。