HSQL 和 Hibernate - 许多删除语句上的内存不足错误

Posted

技术标签:

【中文标题】HSQL 和 Hibernate - 许多删除语句上的内存不足错误【英文标题】:HSQL and Hibernate - Out Of Memory error on many Delete Statements 【发布时间】:2016-05-08 15:14:20 【问题描述】:

我们在 java 项目中使用 Hibernate 3.6.10.Final 和 HSQL 2.3.2。 我有一个可重现的内存不足错误。

在读取堆转储时,我看到占用所有内存的对象是 org.hsqldb.Session,特别是其中包含数十万个 RowAction 对象的 rowActionList。

所有 RowAction 对象都是类型 2,即删除语句。 HSQL 属性 hsqldb.cache_rowshsqldb.cache_size 设置为默认值,我认为分别是 50,000 和 10,000。

自从提出这个问题后,我们发现这个OOM发生在以下场景:

    我们在大量数据上运行应用程序,这会导致大量插入语句(数十万条),并且我们在不正确关闭数据库的情况下关闭了应用程序(我们无法正确关闭,因为我们有一个关闭的时间非常有限)。这是第一次运行后的数据库:

    然后我们再次运行该应用程序,我认为一旦我们打开一个与数据库的休眠会话,内存就会开始以几秒钟的方式膨胀执行任何删除语句。 第二次运行后: 我们现在认为这是由 HSQLDB 执行的检查点引起的,该检查点是由于不正确的关闭而发生的。

我们是否正确,如果正确,为什么检查点进程会占用这么多内存?

我在原始问题中谈论的删除语句很可能是不相关的:

所有这些删除语句都在同一个休眠会话下完成。

对于我们执行的每个删除操作:

    transaction = session.beginTransaction();
    session.delete(file);
    transaction.commit();

谢谢

【问题讨论】:

如果事务实际已提交,则不会发生这种情况。启用 SQL 日志记录并查看发送到 HSQLDB 的内容。 感谢@fredt 的帮助,我已经更新了这个问题,因为我们现在认为这是由其他情况引起的,所以不确定您是否仍然认为 SQL 日志会有所帮助。 这肯定是通过 Hibernate 连接造成的。 DELETE 或 UPDATE 语句创建 RowAction 对象。 【参考方案1】:

我们终于找到了 DELETE 语句占用所有内存的原因。 事实证明,在第二次运行中,我们尝试使用 TRUNCATE TABLE 语句截断在第一次运行中创建的表。

TRUNCATE TABLE 命令在单个事务中完成,因此截断之前的状态保存在内存中,如下所述: Truncating takes too much time hsqldb

当切换到 TRUNCATE TABLE tableName AND COMMIT 时,不会发生 OOM。

【讨论】:

以上是关于HSQL 和 Hibernate - 许多删除语句上的内存不足错误的主要内容,如果未能解决你的问题,请参考以下文章

在语句中找不到 Spring Hibernate JPA HSQL 表

hibernate HQL语句 类名大小写问题

Hibernate、Spring 和 HSQL:找不到表异常

用于 HSQL 的宠物诊所 hibernate.dialect

Hibernate 4、JPA 2 和 HSQL,无法通过 ID 查询

为啥 Hibernate 将模式名称添加到 Hsql 函数?