2

私のアプリケーションは、大量のジオメトリ データを抽出します。Eclipselink 2.4.1 を使用して、そのデータを MySQL データベースに永続化します。アプリケーションはバッチ スタイルで動作します。つまり、データのセットを収集し、それを永続化し、次のセットに進み、それを永続化します。後で別のアプリケーションがそのデータを読み取って処理しますが、この質問はデータを収集する最初のアプリケーションに関するものにすぎません。

データ収集アプリケーションはかなりの時間実行されます。EntityManagers起動時に作成され、アプリケーションが終了するまで有効な固定セットを使用します。抽出はマルチスレッドであり、スレッドごとに 1 つの EntityManager があります。私の問題は、キャッシュをどのように構成しても、しばらくするとEclipseLinkがすべてのメモリを使い果たし、しばらくするとOutOfMemoryError.

を使用VisualVMして分析したヒープダンプを抽出していEclipse Memory Analyzerました。によって疑わしい量のメモリが保持されていEntityManagerImpl.extendedPersistenceContext.cloneMappingます。このマップは、ジオメトリ データ オブジェクトへの参照を保持します。時間の経過とともに、このマップのサイズが数百メガバイトになり、それがメモリ不足エラーの原因になります。

私はすでに次のことを試しました:

  • を構成して弱参照を使用していますeclipselink.persistence-context.reference-mode=weakEntityManagerImpl.extendedPersistenceContext.cloneMappingがタイプであることを確認しましたIdentityWeakHashMap弱いキャッシュに関するドキュメントから、参照モードを使用weakすると問題が解決することが期待できます。残念ながら、ガベージ コレクターはまだエントリを要求しておらず、メモリ不足エラーが発生し続けています。
  • でキャッシュを完全にオフにしようとしましたeclipselink.cache.shared.default=false。問題は解決しません。

ここで何が起こっているのか、その問題をどのように解決できるかについて、誰か提案がありますか? また、問題を回避する方法の提案も受け付けています。

4

1 に答える 1

2

いくつかのこと。

まず、長期間有効な EntityManager を保持しないでください。トランザクションごと、またはリクエストごとに新しい EntityManger を作成する必要があります。

次に、アプリケーション (静的変数など) がオブジェクトへの参照を保持していないことを確認します。何かがオブジェクトを参照している場合、ガベージ コレクションは行われません。

于 2012-12-17T15:06:57.573 に答える