11

Java アプリケーションでメモリ リークが遅くなります。これは、使用時に Entitymanager を常に閉じるとは限らないことが原因である可能性があるのではないかと考えていました。ただし、myeclipse を使用して DB コードを生成すると、次のようなメソッドが得られます。

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 のどちらが正しいのか疑問に思っています。

4

4 に答える 4

6

@Ruggsが言ったように、EntityManagerのライフサイクルを自分で管理している場合(J2EEによってCMP Container Managed Persistenceを実行するのではなく)、EntityManagerを自分で閉じるか、少なくともEntityManager.clear()エンティティをデタッチするために呼び出す必要があります。

EntityManagerは軽量オブジェクトであるため、1つだけ持つ必要はありません。トランザクションごとに作成し、トランザクションがコミットされた後に閉じることができます。

EntityManagerを介してロード/永続化するすべてのエンティティは、エンティティを明示的にデタッチするまで(EntityManager.detach()またはEntityManager.clear()またはを介してEntityManager.close())メモリに残ります。したがって、短命のEntityManagerを使用することをお勧めします。OOMEを取得した後、同じEntityManagerを介して1000000エンティティをデタッチせずに永続化する場合(各エンティティを独自の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();
}
于 2010-02-12T18:37:05.157 に答える
1

エンティティ マネージャーは通常、アプリケーションと同じライフサイクルを持つ必要があり、要求ごとに作成または破棄されることはありません。

あなたの「メモリリーク」は、JPAが行っているキャッシングに過ぎないかもしれません。どのJPAプロバイダーを使用しているかはわかりませんが、経験から、EclipseLinkはデフォルトで広範なキャッシングを行うことがわかっています(これは、JPAとORMの一般的な利点の一部です)。

メモリリークがあることをどうやって知るのですか?

于 2009-04-01T16:08:28.820 に答える