繁体   English   中英

session.flush如何帮助内存释放?

[英]How session.flush is helping in memory release here?

正如flush docs java中所述

刷新是将底层持久存储与内存中保持的可持久状态同步的过程。

以下是我对上述陈述的理解

因此,如果某人正在执行插入/更新然后刷新,那么额外插入的行将仅位于Java内存中。 但是其他方式,即Db数据将仅与提交时在内存中保持的可持久状态同步。

现在让我们通过以上理解

我遇到了HIbernate commit()和flush() ,其中加入的回答告诉session.flush有助于在某些情况下释放内存,从而避免OutOfMemoryException。

当我在下面执行时,line1(session.flush())将对客户表上的20个客户执行插入查询,该查询为列表中的20个客户对象释放内存,但另一方面在客户表下创建20个客户数据行仍然是在java内存中(它将仅在第2行的提交时转到数据库)。 所以我不确定session.flush如何帮助释放内存?

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();


for ( int i=0; i<100000; i++ ) {
    Customer customer = new Customer(.....);
    session.save(customer);
    if ( i % 20 == 0 ) { //20, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush(); //line1
        session.clear();
    }
}

tx.commit();// line2
session.close();

根据API session.flush()

void flush()
           throws HibernateException

强制此会话刷新。 必须在提交事务并关闭会话之前在工作单元的末尾调用(取决于flush-mode,Transaction.commit()调用此方法)。

刷新是将底层持久存储与内存中保持的可持久状态同步的过程。

因此,此方法的目的是将持久状态与基础数据库同步。 如果仍然有对象的引用,它将无助于释放内存。

另请参阅此链接 - 处理大量元素时Hibernate内存不足异常

在您的程序中,您在for-loop中创建100000 Customer 如果没有hibernate代码,那么这意味着您没有维护这些对象的任何引用,因此它们有资格进行垃圾回收。

但是当你说session.save(customer) ,对象与Hibernate的会话相关联,因此它们将被放置在第一级缓存中。

如果对象的数量增加并且没有足够的内存可用,那么当hibernate尝试在内存中维护所有这些对象时,就会出现内存不足的问题。 因此,调用flush方法将使hibernate向数据库调用所需的查询,并且调用clear将帮助它释放第一级缓存中的内存,从而释放一些内存。

更新:

调用session.clear()使hibernate清除内部以第一级缓存形式维护的内存。 session.clear()调用StatefulPersistenceContext.clear() ,它在各种Map和其他对象调用clear()方法 这将清除第一级缓存中的内存。 这清楚地表明对象有资格进行垃圾收集,有助于释放一些内存。 因此,状态不再由Hibernate维护,因此对象处于分离状态。

现在按照API Traansaction.com();

void commit()
            throws HibernateException

刷新关联的会话并结束工作单元(除非我们在FlushMode.MANUAL中。

当且仅当基础事务由此对象启动时,此方法才会提交基础事务。

调用commit()刷新所有挂起的项,然后向底层数据库发出commit

更新:

另请参阅此链接 - flush() 会话 ,其中明确说明在调用flush()方法时会进行JDBC调用。

有时,Session将执行将JDBC连接的状态与内存中保存的对象状态同步所需的SQL语句。 这个过程叫做flush。

除非显式flush(),否则绝对不能保证Session何时执行JDBC调用,只保证它们执行的顺序。

flush()将数据发送到数据库。 如果在Hibernate中激活SQL日志记录,您将看到。 commit()将提交先前发送到数据库的更改。 可能是,您的缓存保留了全部或部分数据。 在这种情况下,您必须调整缓存设置。

也就是说,如果你在内存中有这么多更改或新对象需要进行刷新以避免OutOfmemoryError,那么你可能需要在更深层次上更改你的设计,比如制作多个但是更小的事务。 拥有这么大的事务可以在应用程序和数据库中给您带来问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM