Hibernate实体持续存在巨大内存泄漏,为什么?

Aic*_*ich 4 java persistence memory-leaks hibernate jpa

我将 Hibernate 与 JPA EntityManager 一起使用,而不是 Hibernate 会话。大多数人似乎建议为每个事务使用新的 EntityManager,所以这就是我正在做的事情。

因此,我连续创建了 10000 个新实体。第一次迭代的堆使用量约为 90 MB,最后一次迭代的堆使用量约为 5 GB。

java内存泄漏

这是我的迭代代码:

    Session session = Core.getDatabase().createEntityManager().unwrap(Session.class);
    Query query = session.getNamedQuery("Account.getAllIds");
    query.setReadOnly(true);
    query.setFetchSize(100);
    ScrollableResults accounts = query.scroll(ScrollMode.FORWARD_ONLY);

    EntityManager entityManager = Core.getDatabase().createEntityManager();
    entityManager.getTransaction().begin();

    while (accounts.next()) {

        int id = (int) accounts.get(0);
        Account account = entityManager.getReference(Account.class, id);

        Core.getDatabase().persist(new AccountTest(account));
        changes++;

    }

    entityManager.close();
    accounts.close();
    session.close();
Run Code Online (Sandbox Code Playgroud)

还有我的持久化函数:

public class Database
{
    private final EntityManagerFactory entityManagerFactory;

    public Database(String host, String database, String user, String password)
    {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("javax.persistence.jdbc.url", "jdbc:mysql://" + host + ":3306/" + database);
        properties.put("javax.persistence.jdbc.user", user);
        properties.put("javax.persistence.jdbc.password", password);

        entityManagerFactory = Persistence.createEntityManagerFactory("default", properties);
    }

    public EntityManager createEntityManager()
    {
        return entityManagerFactory.createEntityManager();
    }

    public void persist(Object... objects)
    {
        EntityManager entityManager = createEntityManager();
        entityManager.getTransaction().begin();

        for (Object object : objects) {
            entityManager.persist(object);
        }

        entityManager.getTransaction().commit();
        entityManager.clear();
        entityManager.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,我迭代所有帐户实体(10k,但由于滚动功能而使用 Hibernate Session),并希望为每个帐户创建一个新的 AccountTest。

Vla*_*cea 5

问题是您EntityManager始终保持第一个打开的状态,而只清除并关闭另一个EntityManager仅用于保存一个项目的项目。

最后,您已将所有 Account 实体加载到第一个EntityManager.