Как сказал @Ruggs, если вы сами управляете жизненным циклом EntityManager (вместо того, чтобы J2EE управлял сохранением контейнера CMP), вам необходимо закрыть EntityManager самостоятельно или хотя бы вызвать EntityManager.clear()
для отсоединения сущностей. *
EntityManager - это легкий объект, поэтому вам не нужно просто иметь его, вы можете создать его для каждой транзакции и закрыть его после фиксации транзакции.
Все сущности, которые загружаются / сохраняются через EntityManager, остаются в памяти до тех пор, пока вы явно не отсоедините от них сущности (через EntityManager.detach()
или EntityManager.clear()
или EntityManager.close()
). Так что лучше иметь недолговечных EntityManager. Если вы сохраняете 1000000 сущностей через один и тот же EntityManager, не отсоединяя их после получения OOME (не имеет значения, сохраняете ли вы каждую сущность в ее собственной EntityTransaction).
Это все объяснено в этом посте http://javanotepad.blogspot.com/2007/06/how-to-close-jpa-entitymanger-in-web.html.
В качестве примера (взятого из предыдущего поста), если вы хотите избежать «утечек памяти», вы должны сделать что-то вроде этого (если вы не используете 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();
}