java EntityManager 导致内存泄漏?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/706238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Entitymanager causing memory leak?
提问by GBa
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:
我的 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;
}
}
Which never close the EntityManager. Considering this is generated code, I'm wondering who's right, me or the IDE.
从不关闭 EntityManager。考虑到这是生成的代码,我想知道谁是对的,我还是 IDE。
回答by RubenLaguna
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.
正如@Ruggs 所说,如果您自己管理 EntityManager 生命周期(而不是由 J2EE 完成 CMP Container Managed Persistence),那么您需要自己关闭 EntityManager 或至少调用EntityManager.clear()分离实体。
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.
EntityManager 是轻量级对象,因此不需要只有一个,您可以为每个事务创建一个并在事务提交后关闭它。
All the entities that load/persist through an EntityManager stay in memory until you explicitly detach the entities from it (via EntityManager.detach()or EntityManager.clear()or EntityManager.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).
通过 EntityManager 加载/保留的所有实体都保留在内存中,直到您显式地将实体与其分离(通过EntityManager.detach()或EntityManager.clear()或EntityManager.close())。所以最好有短命的 EntityManagers。如果您通过同一个 EntityManager 保留 1000000 个实体而不分离它们,您将获得 OOME(如果您将每个实体保留在它自己的 EntityTransaction 中,则无关紧要)。
It's all explained in this post http://javanotepad.blogspot.com/2007/06/how-to-close-jpa-entitymanger-in-web.html.
这一切都在这篇文章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):
举个例子(取自之前的帖子),如果你想避免“内存泄漏”,你应该做这样的事情(如果你没有使用 CMP):
EntityManager em = emf.createEntityManager();
try {
EntityTransaction t = em.getTransaction();
try {
t.begin();
// business logic to update the customer
em.merge(cust);
t.commit();
} finally {
if (t.isActive()) t.rollback();
}
} finally {
em.close();
}
回答by cletus
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).
您的“内存泄漏”可能只是 JPA 正在执行的缓存操作。你没有说你使用哪个 JPA 提供者,但我从经验中知道 EclipseLink 默认情况下会进行大量缓存(这是 JPA 和 ORM 所谓的一般好处的一部分)。
How do you know you have a memory leak?
你怎么知道你有内存泄漏?
回答by kohlerm
Check whether it's really a leak
检查是否真的泄漏
if so get the Eclipse Memory Analyzer and analyze it.
如果是这样,请获取Eclipse Memory Analyzer并对其进行分析。
The blog posts heremight also be useful.
此处的博客文章也可能有用。
回答by Ruggs
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.
听起来您正在使用应用程序管理的 EntityManager。您需要自己调用 close EntityManager,它是规范的一部分。关闭 web 应用程序时,您还需要关闭 EntityManagerFactory。
I'd recommend using something like OpenEJB or Springframework to manage the EntityManager/EntityMangerFactory for you.
我建议使用 OpenEJB 或 Springframework 之类的东西来为您管理 EntityManager/EntityMangerFactory。

