0

私のすべてのビジネスメソッドは、新しいEntityManagerを作成し、finallyブロックで明示的に閉じます。

            EntityManagerFactory entityManagerFactory = PersistenceManager.getInstance().getEntityManagerFactory(); //Singleton
            EntityManager em = entityManagerFactory.createEntityManager();
            EntityTransaction tx = em.getTransaction();
            try {
                tx.begin();
                em.persist(someEntity);
                tx.commit();

            } 
            catch (Exception e) {
                e.printStackTrace();
            }
            finally {
                if (em!=null) {
                    em.close();
                }
            }

非常に基本的なpersistence.xmlファイルが定義されています。DB接続情報以外は実際には指定していません。

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="db" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>package.class</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="eclipselink.logging.level" value="INFO" />
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
            <property name="javax.persistence.jdbc.url"
                value="url" />
            <property name="javax.persistence.jdbc.user" value="scott" />
            <property name="javax.persistence.jdbc.password" value=tiger" />
        </properties>
    </persistence-unit>
</persistence>

アプリケーションで見られる動作は、割り当てられたメモリが増加し始め、メモリエラーが発生し始める時点まで最終的に最大制限に達することです。しばらくすると、これらのエラーはクリアされ、JVMに割り当てられたヒープは最大値の約95%に戻ります。確認用のプロファイラーを取り付けていませんが、この時点でGCが発生すると想定しています。

これはデフォルトの動作と見なされますか?キャッシュを調整するためのベストプラクティスのいくつかは何ですか。最大キャッシュサイズを制限するために、persistence.xmlファイルにどのようなプロパティを設定できますか?グローバルに実行できますか、それともエンティティクラスごとに定義する必要がありますか?

4

1 に答える 1

1

プロファイラーでそれを見ずに、何があなたの記憶に保持されているかを言うのは難しい. 最も一般的な原因は、通常、EntityManager をクリアせずに再利用することです。これは、EntityManager がクリアされない限り、その存続期間中、各管理対象エンティティを保持する必要があるためです。エンティティを永続化することを示したコードではそれを行っていませんが、それらをどのように読み取っているかを示していないため、可能である可能性があり、ユーザーがコンテナに任せるのではなく EntityManagers 自体を管理する場合により一般的です彼らのために。

EclipseLink キャッシュに関する質問に答えるには: EclipseLink には、メモリーを保持する第 2 レベルのキャッシュがあります。さまざまなキャッシュ タイプとオプションは、 http: //www.eclipse.org/eclipselink/documentation/2.4/concepts/cache002.htm に示されています。ソフト参照を使用するキャッシュと弱い参照を使用するアイデンティティ マップ。ソフト参照を使用すると、アプリケーションが参照されなくなった場合にオブジェクトをガベージ コレクションできます。デフォルトでは、記述子あたりのサイズは 100 です。

JPA のキャッシュ オプションについては、このページhttp://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching で説明されています。共有キャッシュをオフにして、それがアプリケーションに役立つかどうかを確認できます。私はそれが役立つことに驚くでしょう。ガベージ コレクションが発生した後も、アプリのメモリの 95% がまだ保持されていると述べています。これは、アプリケーションがまだリソースへの参照を持っていることを示しています。

ただし、メモリに保持されているものを確認し、アプリケーション内に問題があるかどうか、またはアプリケーションが構成されているよりも多くのメモリを必要としているかどうかを評価することをお勧めします。

于 2013-02-15T14:15:11.360 に答える