我在线程“HSQLDB Connection @ 3c50507”
中遇到异常java.lang.OutOfMemoryError: Java heap space, when running a JSP.
内存不足的是什么? eclipse,HSQLDB或Tomcat ??我正在使用Mac OS X 10.7.4中的所有内容
当我启动HSQLDB时,我得到了控制台这个例外:
[Server@122ce908]: From command line, use [Ctrl]+[C] to abort abruptly
Exception in thread "HSQLDB Connection @2e716cb7" java.lang.OutOfMemoryError: Java heap space
at org.hsqldb.lib.HsqlByteArrayOutputStream.ensureRoom(Unknown Source)
at org.hsqldb.rowio.RowOutputBinary.ensureRoom(Unknown Source)
at org.hsqldb.lib.HsqlByteArrayOutputStream.write(Unknown Source)
at org.hsqldb.rowio.RowOutputBinary.writeByteArray(Unknown Source)
at org.hsqldb.rowio.RowOutputBinary.writeBinary(Unknown Source)
at org.hsqldb.rowio.RowOutputBase.writeData(Unknown Source)
at org.hsqldb.Result.write(Unknown Source)
at org.hsqldb.Result.write(Unknown Source)
at org.hsqldb.ServerConnection.run(Unknown Source)
at java.lang.Thread.run(Thread.java:680)
这一切意味着什么?
答案 0 :(得分:2)
不是Eclipse。您的“应用程序”未在与Eclipse相同的JVM中运行,并且您发布的最小错误消息清楚地表明,这种情况发生在应用程序中...广义而言。
从您粘贴到问题的最小错误消息中不清楚它是Tomcat还是HSQLDB。我认为它更可能是Tomcat ......并且当你从数据库中提取大量结果集时,问题就出现了。但是,如果没有完整的堆栈跟踪,我只是在猜测。
如果这是我怀疑的,那么你有两个选择:
您可以增加运行Tomcat的JVM的JVM堆大小。
您可以找出触发您的应用程序填充堆的内容。
可能只是您的应用程序设计需要从数据库中提取大量数据并将其保存在内存中。在这种情况下,你别无选择,只能增加堆大小,或者(某种程度上)对“问题大小”强制实施一些限制。
可能是您的应用程序并不真正需要提取所有数据;例如您可以更改SQL查询,以便需要提取更少的数据。
可能您不需要同时将所有数据保存在内存中。
可能是您的应用程序中存在底层内存泄漏,这就是耗尽所有内存的原因。在这种情况下,增加堆大小就像在车祸受害者身上贴上一个绑带。除非你解决了真正的问题,病人才会死。
UPDATE
如果问题出现在您从数据库中提取图像,那么该异常来自数据库端。方法名称表示它是WRITING。堆栈跟踪在HSQLDB控制台上的事实证实这是正确的诊断。 (此时不太可能发生内存泄漏。您只需要增加堆大小......或者不要在数据库中存储大量图像!)
另一方面,如果在将图像存储到数据库时发生,则它位于Tomcat端。其中一个答案有关于如何处理这个问题的链接,
无论哪种方式,从效率的角度来看,将大型图像存储在数据库中并不好,如果你这样做,它可能会给你的数据库/网络服务器基础设施带来压力......就像你所看到的那样。
UPDATE 增加HSQLDB的堆栈大小。
我无法找到增加HSQLDB堆大小的简单“如何”。这取决于您是将其用作嵌入式引擎还是在其自己的JVM中启动HSQLDB。 (我的猜测是你正在做后者。)在前一种情况下,你通过增加嵌入它的应用程序的堆大小来处理问题(例如Tomcat)。否则,如果从命令行启动,请将-Xmx和-Xms参数添加到java
命令行...,如java
手册页中所述。
答案 1 :(得分:0)
可以是hsqldb或Tomcat。不太可能是Eclipse,因为它在运行你的应用程序时会旋转一个单独的JVM。调试它的正确方法是查看堆栈跟踪以查看它是否给出了线索。如果没有,请使用分析器。
答案 2 :(得分:0)
当您在堆上创建太多对象时,通常会发生错误,我怀疑从DB读取时可能会创建太多Strings
。无论哪种方式,问题都与VM和一个解决方案(如果你觉得你的代码不是更好)有关,那就是增加JVM的permgen。
如果您正在使用eclipse进行开发,请尝试increasing the permgen in eclipse。
如果在Tomcat上部署错误,try increasing it in tomcat。