Hibernate - java.lang.OutOfMemoryError:Java堆空间

时间:2011-12-13 09:58:24

标签: java hibernate memory

我得到了这个例外:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:2882)
    at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:100)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:390)
    at java.lang.StringBuilder.append(StringBuilder.java:119)
    at java.util.AbstractMap.toString(AbstractMap.java:493)
    at org.hibernate.pretty.Printer.toString(Printer.java:59)
    at org.hibernate.pretty.Printer.toString(Printer.java:90)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:97)
    at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:35)
    at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:969)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1114)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)

在此代码:

Query query = null;
        Transaction tx= session.beginTransaction();
        if (allRadio.isSelected()) {
            query = session.createQuery("select d from Document as d, d.msg as m, m.senderreceivers as s where m.isDraft=0 and d.isMain=1 and s.organization.shortName like '" + search + "' and s.role=0");
        } else if (periodRadio.isSelected()) {
            query = session.createQuery("select d from Document as d, d.msg as m, m.senderreceivers as s where m.isDraft=0 and d.isMain=1 and s.organization.shortName like '" + search + "' and s.role=0 and m.receivingDate between :start and :end");
            query.setParameter("start", start);
            query.setParameter("end", end);
        }
        final List<Document> documents = query.list();


        query = session.createQuery("select o from Organization as o");
        List<Organization> organizations = query.list(); <---AT THIS LINE
        tx.commit();

我连续2次查询。如果我评论其中一个,那么另一个工作正常。

如果我删除交易,则异常消息会消失。这是怎么回事?这是内存泄漏还是什么?提前谢谢。

3 个答案:

答案 0 :(得分:4)

我从多年的痛苦中汲取了这样的一个小窍门:答案通常被小心地隐藏在堆栈轨迹的前10行中。总是多次读取堆栈跟踪,如果没有提供足够的帮助,请阅读发生故障的方法的源代码。

在这种情况下,问题来自Hibernate漂亮的打印机。这是一个日志记录功能,所以问题是Hibernate正在尝试记录一些巨大的字符串。注意在尝试增加StringBuilder的大小时它是如何失败的。

为什么要尝试记录一个巨大的字符串?我不能从您提供的信息中说出来,但我猜你的组织实体中有一些非常大的东西(可能是BLOB?)而Hibernate正试图记录查询的对象已退出数据库。

最好的选择可能是关闭此特定的日志记录功能。关于一个非常类似的问题有an existing question,答案中有一些有用的建议。

答案 1 :(得分:2)

虽然这样的错误可能是内存泄漏的指示,但它也可能只是因为程序中的内存使用率很高。

您可以尝试通过在命令行中添加以下参数来修改它(这将增加最大堆大小;根据您的需要调整512m):

java -Xmx512m yourprog

如果它以这种方式消失,你的程序可能只需要超过默认大小(这取决于平台);如果它再次出现(可能稍晚一点),你就会在某处发生内存泄漏。

答案 2 :(得分:1)

您需要增加JVM堆大小。使用-Xmx256m命令行参数启动它。