2009-04-01 24 views
9

Javaアプリケーションでメモリリークが遅いです。 Entitymanagerを使用したときに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かを疑問に思っています。

答えて

1

エンティティマネージャは、通常、アプリケーションと同じライフサイクルを持ち、要求ごとに作成または破棄しないでください。

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

あなたはメモリリークがあることをどのように知っていますか?そうthe Eclipse Memory Analyzerを取得し、それを分析する場合、それは本当にleak

のかどうか

+0

私はメモリを持って知っていますアプリケーションが数週間おきにクラッシュし、メモリ不足が発生するため、リークが発生します。それはウェブアプリです。私はeclipselinkを使用しています。私はEMが閉鎖されるべきだと思った: http://stackoverflow.com/questions/220374/do-i-have-to-close-every-entitymanager – GBa

+0

手でEMFを作成していますか? Webアプリケーションでは、受け入れられた答えのように注入する必要があります。その場合は、手動で作成したり閉じたりしてはいけません。この写真には春ですか? – cletus

+0

私はTomcatを使用しているので、EJBがないため、注入することはできません。 EMを作成するためにEntityManagerFactoryを使用しています。私はセッションが期限切れになるとどうにかして、これらがクリーンアップされていないと推測しています。 – GBa

1

チェック。

ブログ投稿hereも役立ちます。

0

アプリケーション管理のEntityManagerを使用しているようです。 EntityManagerを自分で閉じる必要があります。これは仕様の一部です。また、Webアプリケーションを終了するときに、EntityManagerFactoryを閉じる必要があります。

OpenEJBやSpringframeworkのようなものを使ってEntityManager/EntityMangerFactoryを管理することをお勧めします。

6

@RuggsあなたはEntityManagerを管理している場合(CMPコンテナが持続性がJ2EEによって行わ管理するものではなく)自分自身を、ライフサイクル言ったように、あなたは、EntityManagerの自分自身を閉じたり、少なくとも実体を切り離すことEntityManager.clear()を呼び出す必要があります。

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

エンティティをロード/保持するすべてのエンティティは、エンティティを明示的にデタッチするまで(EntityManager.detach()またはEntityManager.clear()またはEntityManager.close())、メモリに残ります。したがって、短命のEntityManagersを持つ方がよいでしょう。 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(); 
} 
関連する問題