我是不是应该经常调用 EntityManager.clear() 以避免内存泄漏?

Posted

技术标签:

【中文标题】我是不是应该经常调用 EntityManager.clear() 以避免内存泄漏?【英文标题】:Am I supposed to call EntityManager.clear() often to avoid memory leaks?我是否应该经常调用 EntityManager.clear() 以避免内存泄漏? 【发布时间】:2011-01-15 15:48:53 【问题描述】:

我是 JPA/OpenJPA 的新手,我注意到如果我在持久化实体后不调用 EntityManager.clear(),我会得到一个 OutOfMemoryError(我会不断在循环中添加新实体)。我不确定这是预期的行为还是仅仅是 OpenJPA 1.2.1 故障。

那么,我是否需要自己明确分离实体? 如果我不是,无论如何这是一个好习惯?

【问题讨论】:

【参考方案1】:

我对 JPA 没有太多经验。不过这会很有用 - 在 JPA 中,您必须: - 为每个事务创建一个新的 EntityManager。 - 在每个事务之后调用 clear() 以清除持久性上下文。

【讨论】:

谢谢。好的,通过答案中的提示,我发现我不应该在应用程序中只使用一个长期存在的 EntityManager。我应该使用方法范围或请求范围 [1]。这将消除调用 em.clear() 的需要。谢谢! [1] javanotepad.blogspot.com/2007/08/… 有用的链接。我曾使用 JPA 和依赖注入(使用 Seam),所以没有遇到类似的问题。 这是不正确的,您不应该在每笔交易中清除 em。如果你每次都这样做,你就没有利用它们。【参考方案2】:

取决于您将多少对象带入持久化过程(读取)。如果您处理大量数字(或某些对象很大),则使用 clear() 可能有意义。每次读取对象时,JPA impl 都应将其放入 L1 缓存中。

【讨论】:

【参考方案3】:

听起来您的设计中某处有问题。通常,一旦实体超出实体管理器的范围,实体就会被分离。这就是您不能在范围之外延迟加载关系的原因之一。

就我的经验而言,我很少使用 em.clear(),如果有的话。我使用了 Hibernate 实现和 Toplink Essentials。还没有使用 OpenJPA 的经验。

【讨论】:

当您说实体被分离时,它超出了实体管理器的范围,您的意思是我应该关闭 EntityManager 并像 Padmarag 建议的那样为每个事务创建一个新的吗?

以上是关于我是不是应该经常调用 EntityManager.clear() 以避免内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

Entitymanager.flush() VS EntityManager.getTransaction().commit - 我应该更喜欢啥?

我应该多久创建一次 EntityManager?

不使用 Spring 获取 EntityManager

spring boot并调用存储过程注释或entityManager?

我应该对扩展 Sonata Base EntityManager 类的类进行单元测试吗?

EntityManager 是不是持有对分离实体的引用?