读取blob字段时出现“java.lang.OutOfMemoryError:Java堆空间”

时间:2014-02-04 11:22:32

标签: java jsp tomcat

我有一个小网站从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的堆空间。

如果我检查堆我有这个结果(对于同一页面有相同的图片):

  • 在我的笔记本电脑上堆积293404672
  • 在服务器上堆75016480

我怎么知道我的代码是否犯了错误,或者是否是服务器问题?

谢谢

4 个答案:

答案 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的内存。这适用于您拥有的每张图片。由于您正在重新调整大小,因此需要两倍的时间(一个缓冲区用于源,一个缓冲区用于目标)。由于您正在处理多个请求,因此需要进一步乘以并发请求的数量。

所以你最终不得不使用相当多的资源。我认为更好的设计是预先扩展图像,然后存储两个版本,然后将这两个版本作为流提供(即不要将它们加载到内存中)。