实体管理器导致内存泄漏?
我的 Java 应用程序中存在缓慢的内存泄漏。 我想知道这是否可能是由于使用时不总是关闭 Entitymanager 造成的。 然而,使用 myeclipse 生成数据库代码,我得到这样的方法:
public Meit update(Meit entity) {
logger.info("updating Meit instance");
try {
Meit result = getEntityManager().merge(entity);
logger.info("update successful");
return result;
} catch (RuntimeException re) {
logger.error("update failed");
throw re;
}
}
永远不会关闭 EntityManager。 考虑到这是生成的代码,我想知道谁是对的,我还是 IDE。
I have a slow memory leak in my Java application. I was wondering if this could be caused by not always closing the Entitymanager when used. However using myeclipse to generate DB code, I'm getting methods like this:
public Meit update(Meit entity) {
logger.info("updating Meit instance");
try {
Meit result = getEntityManager().merge(entity);
logger.info("update successful");
return result;
} catch (RuntimeException re) {
logger.error("update failed");
throw re;
}
}
Which never close the EntityManager. Considering this is generated code, I'm wondering who's right, me or the IDE.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如 @Ruggs 所说,如果您自己管理 EntityManager 生命周期(而不是由 J2EE 完成 CMP 容器管理的持久性),那么您需要自己关闭 EntityManager 或至少调用 EntityManager.clear() 分离实体。
EntityManager 是轻量级对象,因此不需要只拥有一个,您可以为每个事务创建一个并在事务提交后关闭它。
通过 EntityManager 加载/保留的所有实体都会保留在内存中,直到您显式地将实体与它分离(通过 EntityManager.detach() 或 EntityManager.clear() 或 <代码>EntityManager.close())。 因此,最好使用短期的 EntityManager。 如果您通过同一个 EntityManager 保留 1000000 个实体,并且在获得 OOME 后不分离它们(如果您将每个实体保留在其自己的 EntityTransaction 中,则并不重要)。
这一切都在这篇文章中进行了解释 http:// /javanotepad.blogspot.com/2007/06/how-to-close-jpa-entitymanger-in-web.html。
作为一个例子(取自之前的文章),如果你想避免“内存泄漏”,你应该这样做(如果你不使用 CMP):
As @Ruggs said if you are managing the EntityManager lifecycle yourself (as opposed to having CMP Container Managed Persistence done by a J2EE) then you need to close the EntityManager yourself or at least call
EntityManager.clear()
to detach entities.EntityManager are lightweight object so there is no need for just having one, you can create one for each transaction and close it after the transaction is committed.
All the entities that load/persist through an EntityManager stay in memory until you explicitly detach the entities from it (via
EntityManager.detach()
orEntityManager.clear()
orEntityManager.close()
). So it's better to have short-lived EntityManagers. If you persist 1000000 entities via the same EntityManager without detaching them after you will get a OOME (doesn't matter if you persist each entity in it's own EntityTransaction).It's all explained in this post http://javanotepad.blogspot.com/2007/06/how-to-close-jpa-entitymanger-in-web.html.
As an example (taken from the earlier post) if you want to avoid "memory leaks" you should do something like this (if you are not using CMP):
实体管理器通常应具有与应用程序相同的生命周期,并且不应根据每个请求创建或销毁。
您的“内存泄漏”可能只不过是缓存 JPA 所做的事情。 您没有说明您使用哪个 JPA 提供程序,但我从经验中知道 EclipseLink 默认情况下会进行广泛的缓存(这是 JPA 和 ORM 所谓的总体优势的一部分)。
你怎么知道你有内存泄漏?
Entity managers should generally have the same lifecycle as the application and not be created or destroyed on a per-request basis.
Your "memory leak" may be nothing more than the caching JPA is doing. You don't say which JPA provider you use but I know from experience that EclipseLink by default does extensive caching (which is part of the alleged benefits of JPA and ORM in general).
How do you know you have a memory leak?
检查是否确实是泄漏,
如果是的话,请Eclipse 内存分析器并对其进行分析。
此处的博客文章也可能有用。
Check whether it's really a leak
if so get the Eclipse Memory Analyzer and analyze it.
The blog posts here might also be useful.
听起来您正在使用应用程序管理的 EntityManager。 您需要自己调用 close EntityManager,这是规范的一部分。 当您关闭 Web 应用程序时,您还需要关闭 EntityManagerFactory。
我建议使用 OpenEJB 或 Springframework 之类的东西来为您管理 EntityManager/EntityMangerFactory。
It sounds like you are using an application managed EntityManager. You will need to call close the EntityManager yourself, it's part of the spec. You will also need to close the EntityManagerFactory when you shutdown your webapp.
I'd recommend using something like OpenEJB or Springframework to manage the EntityManager/EntityMangerFactory for you.