【问题标题】:Getting java.lang.OutOfMemoryError: Java heap space获取 java.lang.OutOfMemoryError:Java 堆空间
【发布时间】:2012-06-23 05:54:10
【问题描述】:

我在线程“HSQLDB Connection @3c50507”中遇到异常

java.lang.OutOfMemoryError: Java heap space, when running a JSP.

什么是内存不足?日食,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)

这一切意味着什么?

【问题讨论】:

    标签: java eclipse tomcat out-of-memory hsqldb


    【解决方案1】:

    这不是 Eclipse。您的“应用程序”没有在与 Eclipse 相同的 JVM 中运行,并且您发布的最小错误消息清楚地表明,这正在发生在应用程序中......从广义上讲。

    从您粘贴到问题中的最小错误消息中不清楚它是 Tomcat 还是 HSQLDB。我认为它更有可能是 Tomcat ......并且当您从数据库中提取大量结果集时,就会出现问题。但是,如果没有完整的堆栈跟踪,我只是猜测。

    如果这是我的怀疑,那么你有两个选择:

    • 您可以增加运行 Tomcat 的 JVM 的 JVM 堆大小。

    • 您可以找出是什么触发了您的应用程序来填满堆。

      • 可能只是您的应用程序设计要求您从数据库中提取大量数据并将其保存在内存中。在这种情况下,您别无选择,只能增加堆大小,或者(以某种方式)对“问题大小”施加一些限制。

      • 可能是您的应用程序并不真正需要提取所有这些数据;例如您可以更改您的 SQL 查询,以减少需要提取的数据。

      • 您可能不需要同时将所有数据保存在内存中。

      • 可能是您的应用程序中存在底层内存泄漏,而这正是耗尽所有内存的原因。在这种情况下,增加堆大小就像在车祸受害者身上贴绷带一样。除非你解决真正的问题,否则病人会死。


    更新基于迟来的堆栈跟踪

    如果出现问题,您是从数据库中获取图像,那么该异常来自数据库端。方法名称说它是 WRITING。堆栈跟踪位于 HSQLDB 控制台上的事实证实这是正确的诊断。 (此时不太可能发生内存泄漏。您只需要增加堆大小......或者不要在数据库中存储大量图像!)

    另一方面,如果它是在您将图像存储到数据库时发生的,那么它是在 Tomcat 端。其他答案之一有一个关于如何处理的链接,

    无论哪种方式,从效率的角度来看,将大图像存储在数据库中并不好,并且如果这样做可能会给您的数据库/网络服务器基础架构带来压力......就像您所看到的那样。


    更新关于增加 HSQLDB 的堆栈大小。

    我找不到增加 HSQLDB 堆大小的简单“方法”。这取决于您是将它用作嵌入式引擎还是在其自己的 JVM 中启动 HSQLDB。 (我的猜测是您正在做后者。)在前一种情况下,您可以通过增加嵌入它的应用程序(例如 Tomcat)的堆大小来处理问题。否则,如果您从命令行启动,请将 -Xmx 和 -Xms 参数添加到java 命令行...如java 手册页中所述。

    【讨论】:

    • 我刚刚粘贴了整个堆栈跟踪,你能看一下吗??
    • 我认为问题在于,我是从我的数据库图像中获取的!那么,如何增加堆大小??
    • 您必须在 JVM 启动期间通过指定堆参数来增加堆大小。所以,这取决于你如何启动 Tomcat。你是怎样做的?此外,如果您使用图像,了解如何使用它们也很重要:您是否在进行某种图像处理?只是将它们从数据库流式传输到客户端?还有什么?您可能存在架构缺陷,导致您使用的内存超出实际需要。
    • @ChristopherSchultz - 挑剔 - 目前还不清楚 OOME 是否在 Tomcat JVM 中......
    【解决方案2】:

    可以是 hsqldb 或 Tomcat。不太可能是 Eclipse,因为它在运行您的应用程序时会分离出一个单独的 JVM。调试它的正确方法是查看堆栈跟踪以查看它是否提供了线索。如果没有,请使用分析器。

    【讨论】:

    • 我刚刚粘贴了整个堆栈跟踪,你能看一下吗??
    • 这个堆栈跟踪并没有告诉我们太多。你可能会去你的源中发生它的地方,看看你是否在不必要地填充内存。
    • 当我尝试从数据库中获取一些图像时出现此堆栈跟踪
    【解决方案3】:

    当您在堆上创建太多对象时通常会发生该错误,我怀疑您在从数据库读取时创建了太多Strings。无论哪种方式,问题都与 VM 有关,一种解决方案(如果您不觉得自己的代码可能更好)是增加 JVM 的 permgen。

    如果你在 Eclipse 中开发,试试increasing the permgen in eclipse

    如果你部署在Tomcat上出现错误,try increasing it in tomcat

    【讨论】:

    • 这不是 permgen 问题。如果是,异常消息会这样说。增加 permgen 是个坏建议。
    • 好点,然后他需要jvm上的-Xmx标签来增加java允许使用的内存。
    猜你喜欢
    • 2010-12-08
    • 2015-05-14
    • 2019-07-10
    • 2019-12-12
    相关资源
    最近更新 更多