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。
hsqldb.cache_rows
和 hsqldb.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、Spring 和 HSQL:找不到表异常
用于 HSQL 的宠物诊所 hibernate.dialect