什么时候是clear()的好时机?它有很大的性能成本吗?
刷新更改后,应按固定的时间间隔,最好与JDBC批处理大小相同。该文档在有关批处理的章节中描述了常见的成语:
13.1。批量插入
在使新对象持久化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(); session.clear(); }}tx.commit();session.close();
与此相反,这不应该 降低 性能 成本 :
- 它可以使要跟踪的污物数量保持在较低水平(因此冲洗应该很快),
- 它应该允许回收内存。
为什么不自动释放bar或baz之类的对象/ GCd?在提交后将它们保留在会话中有什么意义(在下一个迭代循环中它们始终无法访问)?
clear()如果您不想跟踪实体,就需要显式地进行会话,仅此而已(它可能是这样工作的(一个人可能想提交事务而不“丢失”实体))。
但是据我所知,bar和baz实例应在清除后成为GC的候选对象。分析内存转储以查看发生了什么会很有趣。
直接调用org.hibernate.Session#clear()是否安全/建议
只要您
flush()有待执行的更改而不丢失它们(除非这是您想要的),我就不会发现任何问题(您当前的代码每100个循环会丢失一次create,但这也许只是一些伪代码)。
如果对上述问题的回答是正确的,假设在循环内调用了clear(),对象foo将会发生什么?如果foo.foo()是延迟加载方法怎么办?
调用
clear()将所有加载的实例从中逐出
Session,使它们成为分离的实体。如果后续调用要求实体被“附加”,它将失败。



